在企业级运用项目开拓过程中,Mybatis的For Each In查询功能相信各位小伙伴都遇见过,特殊是在一些多表关联,根据Id IN查询的场景,干系各位小伙伴多多少少都是有见过的!
下面,Debug将给各位小伙伴演示一下当 IN 查询的数据量过大时,采取For Each遍历、拼接实现的办法的弊端。
(1)直接上一个单元测试方法的代码吧:

@Test public void method3() throws Exception{ //待批量查询的 列元素 列表 List<Integer> list=userMapper.selectAllIds(); //查询详细的实体工具列表 List<User> users=userMapper.selectByIds(list); log.info(\"大众--获取查询结果列表:{}\"大众,users); }
个中,userMapper.selectAllIds();方法是前往数据库表codes拿出所有的item_id,然后调用userMapper.selectByIds(list); 方法查询出 指定的 id 列表内的用户实体工具列表信息。其源代码分别如下所示:
<select id=\"大众selectAllIds\"大众 resultType=\公众java.lang.Integer\公众> SELECT item_id FROM codes </select><select id=\公众selectByIds\"大众 resultType=\公众com.debug.springboot.model.entity.User\"大众 parameterType=\"大众java.util.List\公众> SELECT <include refid=\"大众Base_Column_List\"大众/> FROM user <where> id IN <foreach collection=\"大众list\"大众 item=\"大众item\"大众 separator=\"大众,\"大众 open=\公众(\"大众 close=\"大众)\"大众 index=\公众\公众> #{item,jdbcType=VARCHAR} </foreach> </where> </select>
值得一提的,codes数据库表中的所有id一共有 37w 多条,如下图所示:
接下来,我们点击“运行该单元测试方法”,一起见识一下会发生什么事情:
从该运行结果报错的信息来看,Packetfor query is too large (7910580 > 4194304). You can change this value on theserver by setting the max_allowed_packet' variable
表示 待查询的数据量太大了,已经超过了指定可许可的容量了(实在也就间接影响了查询链接的断开与否了!
)
办理方法一可以考试测验去设置 “max_allowed_packet”属性的值,但是这只是治标不治本,不能从根本上进行办理!
而且,ForEach 在数据量大的情形也其实会花费更多的内存、建立的与数据库链接所占用的资源毫无疑问会面临“断开”的风险。。。
于是乎,我们奥妙的想到了第二种方法,即很多人诟病的“$查询”,不才面大家会看到“曾经被别人讨厌的东西,如今看来却起到了很大的浸染!
”
(2)调度后的源代码如下所示:
@Test
public void method4() throws Exception{
//待批量查询的 列元素 列表
List<Integer> list=userMapper.selectAllIds();
//利用mybatis $ 静态取值的特性,将其转化为 元素拼接的String 常量值
List<User> users=userMapper.selectByStrIds(Joiner.on(\"大众,\"大众).join(list));
log.info(\"大众--获取查询结果列表:{}\"大众,users);
}
向右滑动查看
我们在这里利用的正是 $ 静态特性,将查询出来的大批数据量的 列元素列表转化为 String常量值,塞到数据库Mybatis查询时直接静态获取、复制即可,而不须要 For Each 遍历、赋值、拼接再 IN 查询了,其源代码如下所示:
<select id=\"大众selectByStrIds\公众 resultType=\公众com.debug.springboot.model.entity.User\"大众> SELECT <include refid=\"大众Base_Column_List\公众/> FROM user WHERE id IN (${ids}) </select>
点击运行,会创造,一点毛事都木有了,而且运行得出的结果还很快(各位小伙伴可以将数据量提升到百万级别然后进行自测试试!
)
好了,本篇文章我们就先容到这里了,在数据量过大的情形下,建议各位小伙伴采取这种办法进行实现!
其他干系的技能,感兴趣的小伙伴可以关注底部Debug的技能"大众年夜众号,或者加Debug的vx,拉你进群!
一起学习、共同发展!