写在前面
更多知识总结见Mybatis-Plus专栏
内容总结自尚硅谷杨博超老师的视频
博主对于该知识尚在学习阶段
如果发现存在问题请毫不吝啬的指出
扎哇太枣糕的博客首页
Wrapper条件构造器
条件构造器wrapper就是用来封装CRUD方法参数条件的一个接口,其底层有很多的子类,最主要的就是最下面的四个子类:
因为增删改查中的增加记录不需要条件即可完成,所以增加方法无需条件构造器wrapper,其他的删改查则是有这个条件构造器参数的
组装查询条件
查询条件为:名字里包含a字母、年龄在20~30之间、email不为空的所有值,且查询到的值按照年龄降序排序,若年龄相同则按照id升序排序
查询返回name、age、email字段@Test public void selectListTest() { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.select("name", "age", "email") .like("name", "a") .between("age", 20, 30) .isNotNull("email") .orderByDesc("age") .orderByAsc("id"); // SELECT id,name,age,email,is_deleted FROM user WHERE is_deleted=0 AND (name LIKE ? AND age BETWEEN ? AND ? AND email IS NOT NULL) ORDER BY age DESC,id ASC List<Map<String, Object>> maps = mapper.selectMaps(queryWrapper); maps.forEach(System.out::println); System.out.println("========================================================================================"); List<User> users = mapper.selectList(queryWrapper); users.forEach(System.out::println); }
⚠ selectMaps和selectList的区别在于:selectMaps会将查询到的结果封装在一个元素类型为map集合的list集合中,集合中只有查询返回字段所对应的键值对;而selectList的返回值也是一个list集合,只不过元素类型为对应的泛型,包含泛型所有的字段,查询返回字段之外的值都为null组装删除条件
删除条件:email不为空@Test public void deleteTest() { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.isNull("email"); // UPDATE user SET is_deleted=1 WHERE is_deleted=0 AND (email IS NULL) int result = mapper.delete(queryWrapper); System.out.println("删除的行数为" + result); }
组装修改条件
修改条件:(年龄大于20并且用户名中包含有a)或邮箱为null@Test public void updateTest() { User user = new User(); user.setAge(20); user.setEmail("temporary.com"); QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.gt("age", 20) .like("name", "a") .or() .isNull("email"); // UPDATE user SET age=?, email=? WHERE is_deleted=0 AND (age > ? AND name LIKE ? OR email IS NULL) int result = mapper.update(user, queryWrapper); System.out.println("修改的行数为" + result); }
使用queryWrapper组装复杂条件的时候,存在一个且或条件的优先级问题,也就是说在实现多条件拼接的时候且或条件该如何拼接到一起,接下来就挑取两个例子来了解一下
// (年龄大于20并且用户名中包含有a) 或 邮箱为null
// UPDATE user SET age=?, email=? WHERE is_deleted=0 AND (age > ? AND name LIKE ? OR email IS NULL)
queryWrapper.gt("age", 20)
.like("name", "a")
.or()
.isNull("email");
// 用户名中包含有a 且 (年龄大于18或邮箱为null)
// UPDATE user SET age=?, email=? WHERE is_deleted=0 AND (name LIKE ? AND (age > ? OR email IS NULL))
queryWrapper.like("name", "a")
.and(i -> i.gt("age", 18).or().isNull("email"));
总结一下:Lambda表达式中的条件会被当做一个整体优先执行,如果不括起来影响结果的话就需要使用Lambda表达式的写法,具体的使用要根据业务SQL语句来定
@Test
public void sonSelectTest() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.inSql("id", "select id from user where id <= 100");
// SELECT id,name,age,email,is_deleted FROM user WHERE is_deleted=0 AND (id IN (select id from user where id <= 100))
List<User> users = mapper.selectList(queryWrapper);
users.forEach(System.out::println);
}
组装修改条件
修改条件:用户名中包含有a并且(年龄大于20或邮箱为null)@Test public void updateWrapperTest() { UpdateWrapper<User> updateWrapper = new UpdateWrapper<>(); updateWrapper.like("name", "a") .and(i -> i.gt("age", 20).or().isNull("email")); updateWrapper.set("name", "小黑").set("email", "dhsjfghr"); // UPDATE user SET name=?,email=? WHERE is_deleted=0 AND (name LIKE ? AND (age > ? OR email IS NULL)) int result = mapper.update(null, updateWrapper); System.out.println("修改的行数为" + result); }
由SQL可见,使用updateWrapper和queryWrapper完成的修改功能一样,且调用的方法也一样(mapper.update),二者的区别就是updateWrapper不用创建实体类对象,直接使用set方法就可以设置修改的字段值
在实际开发中,不管是queryWrapper还是updateWrapper都应该在一定的判断下再去使用条件构造器拼接条件,比如说请求传过来的值在不为空的情况下才去对这个字段进行条件设置,比如下面的这段代码
@Test
public void ifTest() {
String userName = "";
Integer ageBegin = 20;
Integer ageEnd = 30;
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
if (StringUtils.isNotBlank(userName)) {
queryWrapper.like("name", userName);
}
if (ageBegin != null) {
queryWrapper.ge("age", ageBegin);
}
if (ageEnd != null) {
queryWrapper.le("age", ageEnd);
}
List<User> users = mapper.selectList(queryWrapper);
}
然而,上面的代码使用了很多的if判断显得过于冗余,于是许多的方法都带有一个condition参数,当这个参数为true的时候才会拼接查询条件,下面的代码用来代替上面一堆的if判断
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like(StringUtils.isNotBlank(userName), "name", userName)
.ge(ageBegin != null, "age", ageBegin)
.le(ageEnd != null, "age", ageEnd);
lambdaXxxWrapper与xxxWrapper的区别就是:他们可以使用Lambda的方式直接调用对象的getter方法来指定字段,而不用对照数据库中的字段名,这样就乐意避免参数对应不上数据库字段的问题。除了在调用字段时的写法不一样之外,其他的写法上二者的方式都一样
@Test
public void lambdaQueryWrapperTest() {
String userName = "";
Integer ageBegin = 20;
Integer ageEnd = 30;
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.like(StringUtils.isNotBlank(userName), User::getName, userName)
.ge(ageBegin != null, User::getAge, ageBegin)
.le(ageEnd != null, User::getAge, ageEnd);
List<User> users = mapper.selectList(lambdaQueryWrapper);
}
@Test
public void lambdaUpdateWrapperTest() {
LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.like(User::getName, "a")
.and(i -> i.gt(User::getAge, 20).or().isNull(User::getEmail));
lambdaUpdateWrapper.set(User::getName, "小黑").set(User::getEmail, "dhsjfghr");
// UPDATE user SET name=?,email=? WHERE is_deleted=0 AND (name LIKE ? AND (age > ? OR email IS NULL))
int result = mapper.update(null, lambdaUpdateWrapper);
System.out.println("修改的行数为" + result);
}
这篇博客参加了几何大佬的社区活动
还望大家多多支持几何大佬的社区
⇩ ⇩ ⇩ ⇩ ⇩ ⇩
CSDN社区 《创作达人》活动,只要参与其中并创作文章就有机会获得官方奖品:精品日历、新程序员杂志,快来参与吧!链接直达 https://bbs.csdn.net/topics/605272551