Mybatis-Plus条件构造器笔记
Mybatis-Plus官方文档:https://baomidou.com/pages/10c804/
本文主要讨论Mybatis-Plus条件构造器的区别和用法
- QueryWrapper、UpdateWrapper
- lambdaQueryWrapper、LambdaUpdateWrapper
- QueryChainWrapper、UpdateChainWrapper
- LambdaQueryChainWrapper、LambdaUpdateChainWrapper
创建Wrapper
以 Query* 为例:
QueryWrapper queryWrapper1 = Wrappers.query();
QueryWrapper queryWrapper2 = new QueryWrapper();
LambdaQueryWrapper lambdaQueryWrapper1 = Wrappers.query().lambda();
LambdaQueryWrapper lambdaQueryWrapper2 = new QueryWrapper().lambda();
QueryChainWrapper<User> userQueryChainWrapper = ChainWrappers.queryChain(userMapper);
LambdaQueryChainWrapper<User> userLambdaQueryChainWrapper = ChainWrappers.lambdaQueryChain(userMapper);
Wrapper区别
-
带 lambda 的 wrapper 进行列名匹配时,使用的是 Lambda 的语法,属于函数式编程,偏向于对象。反之不带lambda的就需要手动指定列名(即进行硬编码数据库中的字段名)
-
不带 chain 的 wrapper(QueryWrapper、lambdaQueryWrapper等)执行时,需要将封装的 wrapper 提供给 Mapper,调用Mapper的方法,才可以使用。而带 chain 的 wrapper (QueryChainWrapper、LambdaQueryChainWrapper等)可以直接链式调用数据执行操作的方法
Wrapper用法
Query操作
根据条件查询列表
条件构造器
HashMap<String, Object> map = new HashMap<>();
map.put("1", "12");
userMapper.selectByMap(map);
QueryWrapper<User> wrapper = new QueryWrapper<User>()
.like("email", "24252")
.between("age", 20, 22)
.or()
.eq("name", "zcx")
.orderByAsc("age")
.last("limit 0,3");
List<User> list = userMapper.selectList(wrapper);
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<User>()
.like("email", "24252")
.between(User::getAge, 20, 22)
.eq("name", "zcx")
.orderByAsc(User::getAge);
List<User> list = userMapper.selectList(lambdaQueryWrapper);
LambdaQueryChainWrapper<User> lambdaQueryChainWrapper = new LambdaQueryChainWrapper<>(userMapper)
.like("email", "24252")
.between(User::getAge, 20, 22)
.eq("name", "zcx")
.orderByAsc(User::getAge);
List<User> list = lambdaQueryChainWrapper.list();
Update操作
根据条件更新
简单更新
User user = new User();
user.setUserId(1);
user.setAge(18);
Integer rows = userMapper.updateById(user);
条件构造器
User user = new User();
user.setAge(18);
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("name", "susan");
Integer rows = userMapper.update(user, updateWrapper);
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("name","susan").set("age", 18);
Integer rows = userMapper.update(null, updateWrapper);
LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.eq(User::getName, "susan").set(User::getAge, 18);
Integer rows = userMapper.update(null, lambdaUpdateWrapper);
LambdaUpdateChainWrapper<User> lambdaUpdateChainWrapper = new LambdaUpdateChainWrapper<>(userMapper);
boolean update = lambdaUpdateChainWrapper.eq(User::getName, "susan").set(User::getAge, 18).update();
问题记录
使用 LambdaQueryWrapper 动态添加过滤条件
实体bean
@Data
public class CallLogForm {
@ApiModelProperty(value = "开始时间")
private LocalDateTime beginTime;
@ApiModelProperty(value = "结束时间")
private LocalDateTime endTime;
@ApiModelProperty(value = "调用方")
private String client;
@ApiModelProperty(value = "被调用方")
private String server;
@ApiModelProperty(value = "接口名称")
private String interName;
@ApiModelProperty(value = "状态 0失败 1成功")
private String status;
}
开始
LambdaQueryWrapper<CallLog> wrapper = new LambdaQueryWrapper<CallLog>()
.eq(StringUtils.isNotEmpty(form.getClient()), CallLog::getClient, form.getClient())
.eq(StringUtils.isNotEmpty(form.getServer()), CallLog::getServer, form.getServer())
.ge(form.getBeginTime() != null, CallLog::getOperateDate, form.getBeginTime())
.lt(form.getEndTime() != null, CallLog::getOperateDate, form.getEndTime().plusDays(1))
.like(StringUtils.isNotEmpty(form.getInterName()), CallLog::getInterName, form.getInterName())
.eq(StringUtils.isNotEmpty(form.getStatus()), CallLog::getStatus, form.getStatus());
List<CallLog> list = callLogDao.selectList(wrapper);
注意,下面这个条件构造其实是有问题
.lt(form.getEndTime() != null, CallLog::getOperateDate, form.getEndTime().plusDays(1))
这里,因为对 form.getEndTime()
进行了加1天的操作。刚开始以为前面的为空判断会让程序跳过这个条件构造,但实际上代码判定之前会先执行 form.getEndTime().plusDays(1)
,这样就导致会出现空指针异常。
这里有两种解决办法
-
可以分步写,手动判断空后,再拼接条件构造
LambdaQueryWrapper<CallLog> wrapper = new LambdaQueryWrapper<CallLog>()
.eq(StringUtils.isNotEmpty(form.getClient()), CallLog::getClient, form.getClient())
.eq(StringUtils.isNotEmpty(form.getServer()), CallLog::getServer, form.getServer())
.like(StringUtils.isNotEmpty(form.getInterName()), CallLog::getInterName, form.getInterName())
.eq(StringUtils.isNotEmpty(form.getStatus()), CallLog::getStatus, form.getStatus());
if (form.getBeginTime() != null) {
wrapper.ge(form.getBeginTime() != null, CallLog::getOperateDate, form.getBeginTime());
}
if (form.getEndTime() != null) {
wrapper.lt(form.getEndTime() != null, CallLog::getOperateDate, form.getEndTime().plusDays(1));
}
List<CallLog> list = callLogDao.selectList(wrapper);
-
可以对 form.getEndTime().plusDays(1)
进行改写,避免因为空指针异常导致程序错误,比如封装工具类等,封装也比较简单,这里就不展示代码了
ps,个人感觉这两种方法都不是很好,目前没有更好的方法,之后再更新文章吧。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)