解决mybatis IN语句拼接sql过长

一 前言

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不利于结合其他搜索条件一起查询。例如 全体去重,分批次后需要自己通过集合进行去重整合。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mars'Ares

请我喝杯咖啡吧

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

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

打赏作者

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

抵扣说明:

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

余额充值