MyBatisPlus超詳細分析條件查詢
解決日志冗長的問題
不過測試的時候,控制臺打印的日志比較多,速度有點慢而且不利於查看運行結果,所以接下來我們把這個日志處理下:
取消初始化spring日志打印,resources目錄下添加logback.xml,名稱固定,內容如下:
<?xml version="1.0" encoding="UTF-8"?> <configuration> </configuration>
說明:logback.xml的配置內容,不是我們學習的重點,如果有興趣可以自行百度查詢。
取消MybatisPlus啟動banner圖標
application.yml添加如下內容:
# mybatis-plus日志控制臺輸出
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
banner: off # 關閉mybatisplus啟動圖標
取消SpringBoot的log打印
application.yml添加如下內容:
spring:
main:
banner-mode: off # 關閉SpringBoot啟動圖標(banner)
解決控制臺打印日志過多的相關操作可以不用去做,一般會被用來方便我們查看程序運行的結果。
構建條件查詢
在進行查詢的時候,我們的入口是在Wrapper這個類上,因為它是一個接口,所以我們需要去找它對應的實現類,關於實現類也有很多,說明我們有多種構建查詢條件對象的方式:
先來看第一種:QueryWrapper
@SpringBootTest class Mybatisplus02DqlApplicationTests { @Autowired private UserDao userDao; @Test void testGetAll(){ QueryWrapper qw = new QueryWrapper(); qw.lt("age",18); List<User> userList = userDao.selectList(qw); System.out.println(userList); } }
lt: 小於(<) ,最終的sql語句為
SELECT id,name,password,age,tel FROM user WHERE (age < ?)
第一種方式介紹完後,有個小問題就是在寫條件的時候,容易出錯,比如age寫錯,就會導致查詢不成功
接著來看第二種:QueryWrapper的基礎上使用lambda
@SpringBootTest class Mybatisplus02DqlApplicationTests { @Autowired private UserDao userDao; @Test void testGetAll(){ QueryWrapper<User> qw = new QueryWrapper<User>(); qw.lambda().lt(User::getAge, 10);//添加條件 List<User> userList = userDao.selectList(qw); System.out.println(userList); } }
User::getAget,為lambda表達式中的,類名::方法名,最終的sql語句為:
SELECT id,name,password,age,tel FROM user WHERE (age < ?)
註意:構建LambdaQueryWrapper的時候泛型不能省。
此時我們再次編寫條件的時候,就不會存在寫錯名稱的情況,但是qw後面多瞭一層lambda()調用
接著來看第三種:LambdaQueryWrapper
@SpringBootTest class Mybatisplus02DqlApplicationTests { @Autowired private UserDao userDao; @Test void testGetAll(){ LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>(); lqw.lt(User::getAge, 10); List<User> userList = userDao.selectList(lqw); System.out.println(userList); } }
這種方式就解決瞭上一種方式所存在的問題。
多條件構建
學完瞭三種構建查詢對象的方式,每一種都有自己的特點,所以用哪一種都行,剛才都是一個條件,那如果有多個條件該如何構建呢?
需求:查詢數據庫表中,年齡在10歲到30歲之間的用戶信息
@SpringBootTest class Mybatisplus02DqlApplicationTests { @Autowired private UserDao userDao; @Test void testGetAll(){ LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>(); lqw.lt(User::getAge, 30); lqw.gt(User::getAge, 10); List<User> userList = userDao.selectList(lqw); System.out.println(userList); } }
gt:大於(>),最終的SQL語句為
SELECT id,name,password,age,tel FROM user WHERE (age < ? AND age > ?)
構建多條件的時候,可以支持鏈式編程
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>(); lqw.lt(User::getAge, 30).gt(User::getAge, 10); List<User> userList = userDao.selectList(lqw); System.out.println(userList);
需求:查詢數據庫表中,年齡小於10或年齡大於30的數據
@SpringBootTest class Mybatisplus02DqlApplicationTests { @Autowired private UserDao userDao; @Test void testGetAll(){ LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>(); lqw.lt(User::getAge, 10).or().gt(User::getAge, 30); List<User> userList = userDao.selectList(lqw); System.out.println(userList); } }
or()就相當於我們sql語句中的or
關鍵字,不加默認是and
,最終的sql語句為:
SELECT id,name,password,age,tel FROM user WHERE (age < ? OR age > ?)
null判定
先來看一張圖,
- 我們在做條件查詢的時候,一般會有很多條件可以供用戶進行選擇查詢。
- 這些條件用戶可以選擇使用也可以選擇不使用,比如我要查詢價格在8000以上的手機
- 在輸入條件的時候,價格有一個區間范圍,按照需求隻需要在第一個價格輸入框中輸入8000
- 後臺在做價格查詢的時候,一般會讓 price>值1 and price <值2
- 因為前端沒有輸入值2,所以如果不處理的話,就會出現 price>8000 and price < null問題
- 這個時候查詢的結果就會出問題,具體該如何解決?
需求:查詢數據庫表中,根據輸入年齡范圍來查詢符合條件的記錄
用戶在輸入值的時候,
如果隻輸入第一個框,說明要查詢大於該年齡的用戶
如果隻輸入第二個框,說明要查詢小於該年齡的用戶
如果兩個框都輸入瞭,說明要查詢年齡在兩個范圍之間的用戶
思考第一個問題:後臺如果想接收前端的兩個數據,該如何接收?
我們可以使用兩個簡單數據類型,也可以使用一個模型類,但是User類中目前隻有一個age屬性,如:
@Data public class User { private Long id; private String name; private String password; private Integer age; private String tel; }
使用一個age屬性,如何去接收頁面上的兩個值呢?這個時候我們有兩個解決方案
方案一:添加屬性age2,這種做法可以但是會影響到原模型類的屬性內容
@Data public class User { private Long id; private String name; private String password; private Integer age; private String tel; private Integer age2; }
方案二:新建一個模型類,讓其繼承User類,並在其中添加age2屬性,UserQuery在擁有User屬性後同時添加瞭age2屬性。
@Data public class User { private Long id; private String name; private String password; private Integer age; private String tel; } @Data public class UserQuery extends User { private Integer age2; }
環境準備好後,我們來實現下剛才的需求:
@SpringBootTest class Mybatisplus02DqlApplicationTests { @Autowired private UserDao userDao; @Test void testGetAll(){ //模擬頁面傳遞過來的查詢數據 UserQuery uq = new UserQuery(); uq.setAge(10); uq.setAge2(30); LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>(); if(null != uq.getAge2()){ lqw.lt(User::getAge, uq.getAge2()); } if( null != uq.getAge()) { lqw.gt(User::getAge, uq.getAge()); } List<User> userList = userDao.selectList(lqw); System.out.println(userList); } }
上面的寫法可以完成條件為非空的判斷,但是問題很明顯,如果條件多的話,每個條件都需要判斷,代碼量就比較大,來看MP給我們提供的簡化方式:
@SpringBootTest class Mybatisplus02DqlApplicationTests { @Autowired private UserDao userDao; @Test void testGetAll(){ //模擬頁面傳遞過來的查詢數據 UserQuery uq = new UserQuery(); uq.setAge(10); uq.setAge2(30); LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>(); lqw.lt(null!=uq.getAge2(),User::getAge, uq.getAge2()); lqw.gt(null!=uq.getAge(),User::getAge, uq.getAge()); List<User> userList = userDao.selectList(lqw); System.out.println(userList); } }
d當然這個也可以使用鏈式編程,如果太長瞭就要做些微的調整:
lt()方法
condition為boolean類型,返回true,則添加條件,返回false則不添加條件
到此這篇關於MyBatisPlus超詳細分析條件查詢的文章就介紹到這瞭,更多相關MyBatis條件查詢內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- MyBatisPlus+Lombok實現分頁功能的方法詳解
- MyBatis-Plus實現條件查詢的三種格式例舉詳解
- MyBatis-Plus 查詢指定字段的實現
- Java8 Stream流的常用方法匯總
- mybaties plus selectMaps和selectList的區別說明