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