Mybatis批量查询比较

Mybatis拼装

平时我们一般都是这种写法,传一个list对象进去foreach拼接

List<ProductDto> listByProductIds(@Param("productIds")List<Long> productIds);
<select id="listByProductIds" resultType="com.forlan.product.dto.ProductDto">
	select id,name
	from TB_PROD_PRODUCT
	where STATUS = 1
  	and id in
	<foreach collection="productIds" item="id" open="(" close=")" separator=",">
		#{id}
	</foreach>
</select>

手写代码拼装

优化后的写法,在代码组装好,然后直接传一个字符串进去拼接,直接把in的内容当做一个参数传进去,${}

List<ProductDto> listByCombinationProductIds(@Param("productIds") String productIds);
<select id="listByCombinationProductIds" resultType="com.forlan.product.dto.ProductDto">
	select id,name
	from TB_PROD_PRODUCT
	where STATUS = 1
  	and id in (${productIds});
</select>

效率比较

分别测试了10、100、1000、1W、10W、100W的量级
测试代码

@Autowired
private ProductDao productDao;
@Test
public void test() {
	long number = 10;
	for (int power = 1; power <= 6; power++) {
		List<Long> productIds = new ArrayList<>();
		long total = (long) Math.pow(number, power);
		for (long i = 1; i <= total; i++) {
			productIds.add(i);
		}
		StopWatch stopWatch = new StopWatch("测试" + total + "个拼接");
		
		stopWatch.start("mybatis拼装");
		productDao.listByProductIds(productIds);
		stopWatch.stop();
		
		stopWatch.start("手写代码拼装");
		productDao.listByCombinationProductIds(Joiner.on(",").join(productIds));
		stopWatch.stop();
		
		System.out.println(stopWatch.prettyPrint());
		System.out.println();
	}
}

运行结果

StopWatch '测试10个拼接': running time (millis) = 427
-----------------------------------------
ms     %     Task name
-----------------------------------------
00417  098%  mybatis拼装
00010  002%  手写代码拼装


StopWatch '测试100个拼接': running time (millis) = 21
-----------------------------------------
ms     %     Task name
-----------------------------------------
00012  057%  mybatis拼装
00009  043%  手写代码拼装


StopWatch '测试1000个拼接': running time (millis) = 39
-----------------------------------------
ms     %     Task name
-----------------------------------------
00026  067%  mybatis拼装
00013  033%  手写代码拼装


StopWatch '测试10000个拼接': running time (millis) = 218
-----------------------------------------
ms     %     Task name
-----------------------------------------
00160  073%  mybatis拼装
00058  027%  手写代码拼装


StopWatch '测试100000个拼接': running time (millis) = 1314
-----------------------------------------
ms     %     Task name
-----------------------------------------
00998  076%  mybatis拼装
00316  024%  手写代码拼装


StopWatch '测试1000000个拼接': running time (millis) = 13370
-----------------------------------------
ms     %     Task name
-----------------------------------------
09863  074%  mybatis拼装
03507  026%  手写代码拼装

通过对比不同量级,手写代码拼装的方式,效率高

总结

方式效率
mybatis拼装
手写代码拼接
备注说明

mybatis拼装效率低的原因,实际上是foreach导致

select id,name
	from TB_PROD_PRODUCT
	where STATUS = 1
	and id in
	<foreach collection="productIds" item="id" open="(" close=")" separator=",">
		#{id}
	</foreach>

实际上是先解析成

select id,name 
	from TB_PROD_PRODUCT 
	where STATUS = 1 
	and id in (#{__frch_id_0},  #{__frch_id_1}, #{__frch_id_2})

然后通过PreparedStatment 的 setXXX来进行赋值,就是还要循环解析 #{__frch_item_0} 之类的占位符,foreach 的集合越大,解析越慢。
所以,我们直接使用手写代码拼接,效率就快了很多。

posted @ 2022-06-27 09:43  程序员Forlan  阅读(142)  评论(0编辑  收藏  举报