一、wapper介紹
1、Wrapper家族
在MP中我們可以使用通用Mapper(BaseMapper)實現基本查詢,也可以使用自定義Mapper(自定義XML)來實現更高級的查詢。當然你也可以結合條件構造器來方便的實現更多的高級查詢。
Wrapper : 條件構造抽象類,最頂端父類
AbstractWrapper : 用於查詢條件封裝,生成 sql 的 where 條件
QueryWrapper : 查詢條件封裝
UpdateWrapper : Update 條件封裝
AbstractLambdaWrapper : 使用Lambda 語法
LambdaQueryWrapper :用於Lambda語法使用的查詢Wrapper
LambdaUpdateWrapper : Lambda 更新封裝Wrapper
2、創建測試類
@SpringBootTest
public class WrapperTests {
@Resource
private UserMapper userMapper;
}
二、QueryWrapper
1、例1:組裝查詢條件
查詢名字中包含n,年齡大於等於10且小於等於20,email不為空的用戶
@Test
public void test1() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper
.like("name","n")
.between("age", 10, 20)
.isNotNull("email");
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
2、例2:組裝排序條件
按年齡降序查詢用戶,如果年齡相同則按id升序排列
@Test
public void test2() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper
.orderByDesc("age")
.orderByAsc("id");
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
3、例3:組裝刪除條件
刪除email為空的用戶
@Test
public void test3() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.isNull("email");
int result = userMapper.delete(queryWrapper); //條件構造器也可以構建刪除語句的條件
System.out.println("delete return count = " + result);
}
4、例4:條件的優先級
查詢名字中包含n,且(年齡小於18或email為空的用戶),並將這些用戶的年齡設置為18,郵箱設置為 user@atguigu.com
@Test
public void test4() {
//修改條件
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper
.like("name", "n")
.and(i -> i.lt("age", 18).or().isNull("email")); //lambda表達式內的邏輯優先運算
User user = new User();
user.setAge(18);
user.setEmail("user@atguigu.com");
int result = userMapper.update(user, queryWrapper);
System.out.println(result);
}
5、例5:組裝select子句
查詢所有用戶的用戶名和年齡
@Test
public void test5() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("name", "age");
//selectMaps()返回Map集合列表,通常配合select()使用,避免User對象中沒有被查詢到的列值為null
List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);//返回值是Map列表
maps.forEach(System.out::println);
}
6、例6:實現子查詢
查詢id不大於3的所有用戶的id列表
@Test
public void test6() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.inSql("id", "select id from user where id <= 3");
//selectObjs的使用場景:只返回一列
List<Object> objects = userMapper.selectObjs(queryWrapper);//返回值是Object列表
objects.forEach(System.out::println);
}
但上面的方式容易引發sql注入
queryWrapper.inSql("id", "select id from user where id <= 3 or true"); // 或插敘出所有用戶id
可是使用下面的查詢方式替換
queryWrapper.in("id", 1, 2, 3 );
// 或
queryWrapper.le("id", 3 );
三、UpdateWrapper
例7:需求同例4
查詢名字中包含n,且(年齡小於18或email為空的用戶),並將這些用戶的年齡設置為18,郵箱設置為 user@hguo.com
@Test
public void test7() {
//組裝set子句
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper
.set("age", 18)
.set("email", "user@atguigu.com")
.like("name", "n")
.and(i -> i.lt("age", 18).or().isNull("email")); //lambda表達式內的邏輯優先運算
//這里必須要創建User對象,否則無法應用自動填充。如果沒有自動填充,可以設置為null
User user = new User();
int result = userMapper.update(user, updateWrapper);
System.out.println(result);
}
四、condition
例8:動態組裝查詢條件
查詢名字中包含n,年齡大於10且小於20的用戶,查詢條件來源於用戶輸入,是可選的
@Test
public void test8() {
//定義查詢條件,有可能為null(用戶未輸入)
String name = null;
Integer ageBegin = 10;
Integer ageEnd = 20;
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
if(StringUtils.isNotBlank(name)){
queryWrapper.like("name","n");
}
if(ageBegin != null){
queryWrapper.ge("age", ageBegin);
}
if(ageEnd != null){
queryWrapper.le("age", ageEnd);
}
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
上面的實現方案沒有問題,但是代碼比較復雜,我們可以使用帶condition參數的重載方法構建查詢條件,簡化代碼的編寫
@Test
public void test8Condition() {
//定義查詢條件,有可能為null(用戶未輸入)
String name = null;
Integer ageBegin = 10;
Integer ageEnd = 20;
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper
.like(StringUtils.isNotBlank(name), "name", "n")
.ge(ageBegin != null, "age", ageBegin)
.le(ageEnd != null, "age", ageEnd);
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
五、LambdaXxxWrapper
1、例9:Query - 需求同例8
@Test
public void test9() {
//定義查詢條件,有可能為null(用戶未輸入)
String name = null;
Integer ageBegin = 10;
Integer ageEnd = 20;
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper
//避免使用字符串表示字段,防止運行時錯誤
.like(StringUtils.isNotBlank(name), User::getName, "n")
.ge(ageBegin != null, User::getAge, ageBegin)
.le(ageEnd != null, User::getAge, ageEnd);
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
2、例10:Update - 需求同例4
@Test
public void test10() {
//組裝set子句
LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper
.set(User::getAge, 18)
.set(User::getEmail, "user@atguigu.com")
.like(User::getName, "n")
.and(i -> i.lt(User::getAge, 18).or().isNull(User::getEmail)); //lambda表達式內的邏輯優先運算
User user = new User();
int result = userMapper.update(user, updateWrapper);
System.out.println(result);
}