业务背景
在开发过程中,有一个模糊检索的功能,输入关键词分别对a、b、c三个字段进行模糊查询,并返回按时间倒序的结果列表
初次实现
default PageResult<DO> selectPage(VO vo) {
return selectPage(vo, new LambdaQueryWrapperX<DO>()
.eqIfPresent(DO::getName, reqVO.getName())
.likeIfPresent(DO::getNo, vo.getNo())
.like(DO::getA, vo.getKeyWord())
.or()
.like(DO::getB, vo.getKeyWord())
.or()
.like(DO::getC, vo.getKeyWord())
.orderByDesc(DO::getCreateTime));
}
问题出现
使用该语句的查询的结果与逻辑上的结果并不符合,由于本人第一次写Mybatis-Plus的查询语句,所以也会想当然认为此种方式符合业务逻辑,然而在进一步的探究发现代码实际逻辑并非如此。。。
问题探究
通过查看IDEA后台打印的SQL语句,分析出实际查询的SQL语句如下:
SELECT * FROM tb WHERE name = 0 AND (no LIKE "%m%" AND a LIKE "%n%" OR b LIKE "%n%" OR c LIKE "%n%")
由此可以看到,我思考的查询逻辑是 name AND no AND ( a OR b OR c ),然而实际的查询逻辑却是name AND ( no AND a OR b OR c )
解决方式
此时,需要通过正确的 and() 连接方式将我们的查询逻辑进行“括起来”,通过浏览相关博客,and()的实现是在括号内实现一个Lambda函数,该函数将我们OR的查询逻辑进行限定,最后解决代码如下:
default PageResult<DO> selectPage(VO vo) {
return selectPage(reqVO, new LambdaQueryWrapperX<DO>()
.eqIfPresent(DO::getName, reqVO.getName())
.likeIfPresent(DO::getNo, vo.getNo())
.and(zycdd -> zycdd
.like(DO::getA, vo.getKeyWord())
.or()
.like(DO::getB, vo.getKeyWord())
.or()
.like(DO::getC, vo.getKeyWord())
)
.orderByDesc(DO::getCreateTime));
}