项目场景:
原来项目中大部分复杂的sql语句几乎都用xml写或者一半一半,但热爱研究代码的我,最近终于有了点时间探索一下是不是有些复杂的sql语句也可以用QueryWrapper完全实现,先百度了一下,但结果模糊,没有确切的解决方法,自己经过几个小时的摸索,总算实现了QueryWrapper复杂条件语句的拼接,下面就让我们开始吧!^ _ ^
问题描述:
原来的复杂条件查询语句比如:
SELECT * FROM person WHERE (Id = 1 OR Id = 2 OR ...) AND (Sex = '男' OR Height >= 180)
在person表中查询多个Id里性别为男或身高大于等于180的人的信息。
在xml文件中需要写完整的sql语句,然后再传参。
如果要遍历参数,要用到<foreach>标签,比如:
<foreach collection="idList.split(',')" item="item" index="index" separator="or" open="(" close=")">
find_in_set(#{item},Id)
</foreach>
然而在xml写sql语句还有一点就是MySQL切换Oracle可能会有问题。
原因分析:
这边考虑到目前项目所用到Sql全是采用完整QueryWrapper实现的,项目上有可能会切换数据源,而且实时性方面需求较高,所以比较偏向使用物理分页。
解决方案:
首先,先来拼接WHERE后面关于Id字段遍历的sql语句,代码如下:
QueryWrapper<Person> wrapper = new QueryWrapper<>();
//如果无数据的话,WHERE后面会有括弧(),会导致Sql拼接异常,所以这边先判断
if(IdList.size()>0){
wrapper.or(w->{
for (String Id: IdList) {
w.eq("Id", Id).or();
}
});
}
个人采用Lambda实现遍历赋值,以上这段代码相当于xml文件里的<foreach>标签。
如果括弧里是AND的话 WHERE ( Id = 1 AND Id = 2 AND … ),改成如下:
wrapper.and(w->{
for (String Id: IdList) {
w.eq("Id", Id);
}
});
所以让咱们来用QueryWrapper拼接完整的语句吧!代码如下:
QueryWrapper<Person> wrapper = new QueryWrapper<>();
if(IdList.size()>0){
wrapper.or(w->{
for (String Id: IdList) {
w.eq("Id", Id).or();
}
});
}
wrapper.and(w->{
w.eq("Sex","男").or().ge("Height",180);
});
以下补充Lambda表达式写法:
QueryWrapper<Person> wrapper = new QueryWrapper<>();
if(IdList.size()>0){
wrapper.or(w->IdList.forEach(Id-> w.eq("Id", Id).or()));
}
wrapper.and(w->w.eq("Sex","男").or().ge("Height",180));
如果这篇文章有帮到您的话,不妨点个一键三连吧!^_^