解决mybatis IN语句拼接sql过长

10 篇文章 0 订阅

一 前言

1、mybatis作为轻量级的orm框架被广泛使用 但是也有其不完善地方。例如mybatis对IN语句的支持,自生成IN的辅助查询类不可传空集合

2、oracle在sql中in的元素集合元素个数不能超过1000 但是可以通过多个in的元素集合通过 or进行组合

 

二 解决方案

1、使用mybatis自定义xml编写


 SELECT * FROM TABLE WHERE ID IN
 <foreach collection="Array" index="index" item="item" open="(" close=")">
      <if test="index != 0">
          <choose>
              <when test="index % 1000 == 999"> ) OR ID IN( </when>
              <otherwise>,</otherwise>
          </choose>
      </if>
      #{item}
 </foreach>
          
1、Array为ids集合
2、代码逻辑如下
###open:
(

###index:0
ids[0]

###index:i!=N*1000+999
,
ids[i]

###index:i=N*1000+999
) OR ID IN (
ids[i]

###index:i!=N*1000+999
,
ids[i]

###close:
)

则ql
ID IN(ids[0],ids[1]+...+ids[998])OR ID IN (ids[999],ids[1000],...ids[max])

2、使用代码进行批量查询

//查找节点
if(nodeIdList==null||nodeIdList.isEmpty()){
  //return no match
}

//剩余节点长度   
int nodeSize =nodeIdList.size();

//批处理数量
int batchSize=1000;
        
//批处理次数
int batchNum = (nodeSize-1)/batchSize+1;

//临时处理节点
List<String> temp=new ArrayList<>(batchSize);
 
for (int i = 1; i <= batchNum; i++) {
    if (nodeSize<batchSize) {
           //最后一次不足1000     
           temp = nodeIdList.subList((i-1) * batchSize, (i-1) * batchSize + nodeSize);
         } else {
           temp = nodeIdList.subList((i-1) * batchSize, i * batchSize);
           //剩余节点长度
            nodeSize=nodeSize-batchSize;
         }
         //do search in temp
     }

三 总结

 

 优点缺点
方案一xml编写有助于结合其他条件进行组合查询,例如distinct、count等其他操作代码在xml文件中,需要进行sql层面的维护
方案二使用多次查找的形式有助于通过损耗连接资源的方式加快查询的速度。且次方式可以维护java代码而不用维护sql不利于结合其他搜索条件一起查询。例如 全体去重,分批次后需要自己通过集合进行去重整合。

 

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Mybatis-plus是Mybatis的增强工具,提供了更加方便、快速的开发体验。在实际开发中,我们有时需要动态地拼接SQLMybatis-plus为我们提供了一些丰富的API来进行SQL拼接。 1. Wrapper Wrapper是Mybatis-plus提供的一个用于拼接SQL语句的抽象类。它提供了一系列的查询条件构造方法,比如eq、ne、like等等。使用Wrapper可以有效地避免手写SQL语句时因为类型转换等问题导致的不安全因素,也可以避免SQL注入。 2. LambdaQueryWrapper LambdaQueryWrapper是Wrapper的一个特殊子类,它采用lambda表达式的形式,更加方便地进行拼接。使用LambdaQueryWrapper可以在Java代码中写出和SQL一样的查询条件,比如: LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(User::getName, "张三"); List<User> userList = userService.list(wrapper); 上述代码中,我们使用LambdaQueryWrapper构造了一个查询条件,查询名字为“张三”的用户。可以看到,使用LambdaQueryWrapper的方式非常直观,更加方便。 3. UpdateWrapper UpdateWrapper是用于构造更新操作的Wrapper子类。使用UpdateWrapper可以方便地设置更新的字段和更新条件,比如: UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.set("name", "张三"); wrapper.eq("id", 1); userService.update(wrapper); 上述代码中,我们使用UpdateWrapper构造了一个更新条件,更新名字为“张三”的用户,条件是ID为1。 4. QueryBuilder QueryBuilder是Mybatis-plus提供的一个动态SQL构造器,它可以将多个SQL片段拼接成一条完整的SQL语句。使用QueryBuilder可以更加方便地构建复杂的查询语句。比如: String sql = new QueryBuilder() .select("id", "name", "age") .from("user") .where("age > 18") .orderBy("id DESC") .build(); List<Map<String, Object>> userList = jdbcTemplate.queryForList(sql); 上述代码中,我们使用QueryBuilder构建了一个查询语句,查询所有年龄大于18的用户,按照ID降序排列。 总之,Mybatis-plus提供了众多API来拼接SQL,不管是Wrapper、LambdaQueryWrapper、UpdateWrapper还是QueryBuilder,都可以方便地满足我们的各种SQL拼接需求。开发者可以根据具体情况选择不同的API进行使用,提高代码的开发效率和可读性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mars'Ares

请我喝杯咖啡吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值