1、Wrapper介绍
Wrapper : 条件构造抽象类,最顶端父类
- AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
- QueryWrapper : 查询条件封装
- UpdateWrapper : Update 条件封装
- AbstractLambdaWrapper : 使用Lambda 语法
- LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper
- LambdaUpdateWrapper : Lambda 更新封装Wrapper
本节测试,全部采用Mapper CURD
;创建测试类,路径为src/test/java/com/mybatisplus_demo/MyBatisPlusWrapperTest.java
@SpringBootTest
@RunWith(SpringRunner.class)
public class MyBatisPlusWrapperTest {
@Autowired(required = false)
private UserMapper userMapper;
// 待添加测试方法
}
2、QueryWrapper
a>组装查询条件
@Test
public void testSelectList() {
//查询用户名包含e,年龄在18到24之间,并且邮箱不为null的用户信息
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name", "e").between("age", 18, 24).isNotNull("email");
List<User> users = userMapper.selectList(queryWrapper);
System.out.println(users);
}
b>组装排序条件
public void testSelectList() {
// 按年龄降序查询用户,如果年龄相同则按id升序排列
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("age").orderByAsc("id");
List<User> users = userMapper.selectList(queryWrapper);
System.out.println(users);
}
c>组装删除条件
@Test
public void testDelete(){
// 删除id在3、5、9的用户,并且email为null的用户
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", 3, 5, 9).isNull("email");
int i = userMapper.delete(queryWrapper);
System.out.println(i);
}
此处为逻辑删除,真正执行的是修改
d>组装修改条件
@Test
public void testUpdate(){
// 将(年龄大于20并且用户名中包含有a)或邮箱为null的用户信息修改
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.ge("age", 20).like("name", "a").or().isNull("email");
// 这里必须要创建User对象,否则无法应用自动填充。如果没有自动填充,可以设置为null
User user = new User();
user.setAge(25); // 年龄修改为25
int i = userMapper.update(user, queryWrapper);
System.out.println(i);
}
MySQL中,AND的执行优先级高于OR。也就是说,在没有小括号()的限制下,总是优先执行AND语句,再执行OR语句。
select * from table where 条件1 AND 条件2 OR 条件3
等价于
select * from table where ( 条件1 AND 条件2 ) OR 条件3
与上面等价SQL写法:
@Test
public void testUpdate(){
// 将(年龄大于20并且用户名中包含有a)或邮箱为null的用户信息修改
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// lambda表达式内的逻辑优先运算
queryWrapper.and(i -> i.ge("age", 20).like("name", "a")).or().isNull("email");
// 这里必须要创建User对象,否则无法应用自动填充。如果没有自动填充,可以设置为null
User user = new User();
user.setAge(25); // 年龄修改为25
int i = userMapper.update(user, queryWrapper);
System.out.println(i);
}
e>条件优先级
@Test
public void testUpdate(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//将(年龄大于20并且用户名中包含有a)或(邮箱为null或年龄小于20)的用户信息修改
// lambda表达式内的逻辑优先运算
queryWrapper.and(i -> i.ge("age", 20).like("name", "a"))
.or(i -> i.isNull("email").or().lt("age", 20));
// 这里必须要创建User对象,否则无法应用自动填充。如果没有自动填充,可以设置为null
User user = new User();
user.setAge(25); // 年龄修改为25
int i = userMapper.update(user, queryWrapper);
System.out.println(i);
}
f>组装select子句
①方法一
@Test
public void testSelect(){
// 查询用户信息的username和age字段
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("name", "age");
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
②方法二
@Test
public void testSelect(){
// 查询用户信息的username和age字段
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.select("name", "age");
// selectMaps()返回Map集合列表,通常配合select()使用,避免User对象中没有被查询到的列值变为null
List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);
maps.forEach(System.out::println);
}
g>in子查询
@Test
public void testIn(){
//查询id小于等于3的用户信息(in子句)
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.inSql("id", "select id from t_user where id <= 3");
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
对应的还有
notInSql()
方法,表示not in一般in子句常用于多表查询,此处只是做单表演示
h>exists子查询
@Test
public void testExists(){
//查询用户信息(exists子句)
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.exists("select id from t_user");
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
对应的还有
notExists()
方法,表示not exists一般exists子查询常用于多表查询,此处只是做单表演示
3、UpdateWrapper
a>组装修改条件
@Test
public void testUpdate(){
// 采用UpdateWrapper,组装set子句以及修改条件
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.set("age", 25).and(i -> i.ge("age", 20).like("name", "a")).or().isNull("email");
// 如果没有自动填充,可以设置为null
int i = userMapper.update(null, updateWrapper);
System.out.println(i);
}
虽然QueryWrapper也可以进行修改,但是对于修改语句推荐使用UpdateWrapper
4、condition
在真正开发的过程中,组装条件是常见的功能,而这些条件数据来源于用户输入,是可选的,因此在组装这些条件时,必须先判断用户是否选择了这些条件,若选择则需要组装该条件,若没有选择则一定不能组装,以免影响SQL执行的结果
思路一
@Test
public void testCondition1(){
//定义查询条件,有可能为null(用户未输入或未选择)
String name = null;
Integer ageBegin = 10;
Integer ageEnd = 24;
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// isNotBlank判断某字符串是否不为空且长度不为0且不由空白符(whitespace)构成
if(StringUtils.isNotBlank(name)){
queryWrapper.like("name", name);
}
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 testCondition2(){
//定义查询条件,有可能为null(用户未输入或未选择)
String name = null;
Integer ageBegin = 10;
Integer ageEnd = 24;
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like(StringUtils.isNotBlank(name), "name", name)
.ge(ageBegin != null, "age", ageBegin)
.le(ageEnd != null, "age", ageEnd);
List<User> users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
5、LambdaQueryWrapper
@Test
public void testLambdaQueryWrapper(){
//定义查询条件,有可能为null(用户未输入或未选择)
String name = null;
Integer ageBegin = 10;
Integer ageEnd = 24;
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//避免使用字符串表示字段,防止运行时错误,使用LambdaXxxWrapper后,字段不能再写字符串,只能用函数式接口指定
lambdaQueryWrapper.like(StringUtils.isNotBlank(name), User::getName, name)
.ge(ageBegin != null, User::getAge, ageBegin)
.le(ageEnd != null, User::getAge, ageEnd);
List<User> users = userMapper.selectList(lambdaQueryWrapper);
users.forEach(System.out::println);
}
6、LambdaUpdateWrapper
@Test
public void testLambdaUpdateWrapper(){
// 采用LambdaUpdateWrapper,组装set子句以及修改条件
LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.set(User::getAge, 25)
.and(i -> i.ge(User::getAge, 20).like(User::getName, "a"))
.or()
.isNull(User::getEmail);
// 如果没有自动填充,可以设置为null
int i = userMapper.update(null, lambdaUpdateWrapper);
System.out.println(i);
}