5. MyBatis Plus 条件构造器
大约 3 分钟
五、条件构造器
当我们需要对单表的CURD做复杂条件处理的时候我们就需要借助Wrapper接口来处理,也就是通过条件构造器来处理。
1.Wrapper接口
Wrapper接口是条件构造的抽象类,是最顶级的类
对应的作用描述
2.QueryWrapper
首先来看看QueryWrapper的使用,针对where后的条件封装。
2.1 查询条件
/**
* 查询用户姓名中包含 o 的年龄大于20岁,且邮箱不为null的记录
*/
@Test
void queryUser() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("name","o")
.gt("age",20)
.isNotNull("email");
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
2.2 排序条件
QueryWrapper也可以封装排序的条件
/**
* 根据年龄升序然后根据id降序
*/
@Test
void queryUser() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.orderByAsc("age")
.orderByDesc("uid");
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
2.3 删除条件
QueryWrapper也可以封装删除操作的条件
/**
* 删除所有年龄小于18岁的用户
*/
@Test
void deleteUser() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.le("age",18);
int i = userMapper.delete(wrapper);
System.out.println(i);
}
2.4 组合条件
在封装条件的时候我们可以同时有多个条件组合,类似于 and 和 or的操作,这时QueryWrapper也能很轻松的处理。
/**
* 查询出年龄大于20并且姓名中包含的有'o'或者邮箱地址为空的记录
*/
@Test
void queryUser() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.gt("age",20)
.like("name","o")
.or() // 默认是通过and连接 显示加上 or()方法表示or连接
.isNotNull("email");
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
@Test
void queryUser1() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.and((i)->{
i.gt("age",20).like("name","o");
}).or((i)->{
i.isNotNull("email");
});
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
2.5 查询特定的字段
特殊情况我们需要查询特定的字段,这时可以通过select方法来处理
/**
* 查询出年龄大于20并且姓名中包含的有'o'或者邮箱地址为空的记录
*/
@Test
void queryUser() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.gt("age",20)
.like("name","o")
.or() // 默认是通过and连接 显示加上 or()方法表示or连接
.isNotNull("email")
.select("uid","name","age") // 指定特定的字段
;
//selectMaps()返回Map集合列表,通常配合select()使用,避免User对象中没有被查询到的列值为null
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}
2.6 实现子查询
单表查询中对子查询的需求也是有的,我们来看看如何实现。
/**
* 子查询
* SELECT uid,name,age,email,is_deleted
* FROM t_user
* WHERE (
* uid IN (select uid from t_user where uid < 5)
* )
*/
@Test
void queryUser() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.inSql("uid","select uid from t_user where uid < 5")
;
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}
3.UpdateWrapper
当我们需要组装更新的字段数据的时候,可以通过UpdateWrapper来实现。
/**
* 更新用户Tom的age和邮箱信息
* UPDATE t_user SET age=?,email=? WHERE (name = ?)
*/
@Test
void updateUser() {
UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.set("age",25)
.set("email","bobo@qq.com")
.eq("name","Tom");
int update = userMapper.update(null, wrapper);
System.out.println("update = " + update);
}
4.动态SQL
实际开发中,用户的查询条件都是动态的,我们需要根据不同的输入条件来动态的生成对应的SQL语句,这时我们来看看在MyBatisPlus中是如何处理的。
@Test
void queryUser1() {
String name = "Tom";
Integer age = null;
String email = null;
QueryWrapper<User> wrapper = new QueryWrapper<>();
if(!StringUtils.isEmpty(name)){
wrapper.eq("name",name);
}
if(age != null && age > 0){
wrapper.eq("age",age);
}
if(!StringUtils.isEmpty(email)){
wrapper.eq("email",email);
}
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
上面的代码是通过if来一个个判断的,看起来代码比较复杂,其实大家在前面看相关的API的时候会注意到都会有一个Condition参数
我们可以用这个参数来实现对应的动态SQL处理
@Test
void queryUser2() {
String name = "Tom";
Integer age = null;
String email = null;
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq(StringUtils.isNotBlank(name),"name",name)
.eq(age!=null && age > 0 ,"age" ,age)
.eq(StringUtils.isNotBlank(email),"email",email);
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}