MyBatis 批量插入数据的 3 种方法!( 三 )

经过以上步骤,我们原生的批量插入功能就实现的差不多了,接下来我们使用单元测试来查看一下此方法的执行效率 。
原生批量插入性能测试import com.example.demo.model.User;import com.example.demo.service.impl.UserServiceImpl;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import java.util.ArrayList;import java.util.List;@SpringBootTestclass UserControllerTest {// 最大循环次数private static final int MAXCOUNT = 100000;@Autowiredprivate UserServiceImpl userService;/*** 原生自己拼接 SQL,批量插入*/@Testvoid saveBatchByNative() {long stime = System.currentTimeMillis(); // 统计开始时间List<User> list = new ArrayList<>();for (int i = 0; i < MAXCOUNT; i++) {User user = new User();user.setName("test:" + i);user.setPassword("123456");list.add(user);}// 批量插入userService.saveBatchByNative(list);long etime = System.currentTimeMillis(); // 统计结束时间System.out.println("执行时间:" + (etime - stime));}}然而,当我们运行程序时却发生了以下情况:

MyBatis 批量插入数据的 3 种方法!

文章插图
 
纳尼?程序的执行竟然报错了 。
缺点分析从上述报错信息可以看出,当我们使用原生方法将 10W 条数据拼接成一个 SQL 执行时,由于拼接的 SQL 过大(4.56M)从而导致程序执行报错,因为默认情况下 MySQL 可以执行的最大 SQL(大小)为 4M,所以程序就报错了 。
这就是原生批量插入方法的缺点,也是为什么 MP 需要分批执行的原因,就是为了防止程序在执行时,因为触发了数据库的最大执行 SQL 而导致程序执行报错 。
解决方案当然我们也可以通过设置 MySQL 的最大执行 SQL 来解决报错的问题,设置命令如下:
-- 设置最大执行 SQL 为 10Mset global max_allowed_packet=10*1024*1024;如下图所示:
MyBatis 批量插入数据的 3 种方法!

文章插图
 
注意:以上命令需要在 MySQL 连接的客户端中执行 。
但以上解决方案仍是治标不治本,因为我们无法预测程序中最大的执行 SQL 到底有多大,那么最普世的方法就是分配执行批量插入的方法了(也就是像 MP 实现的那样) 。
当我们将 MySQL 的最大执行 SQL 设置为 10M 之后,运行以上单元测试代码,执行的结果如下:
MyBatis 批量插入数据的 3 种方法!

文章插图
 
总结本文我们介绍了 MyBatis 批量插入的 3 种方法,其中循环单次插入的性能最低,也是最不可取的;使用 MyBatis 拼接原生 SQL 一次性插入的方法性能最高,但此方法可能会导致程序执行报错(触发了数据库最大执行 SQL 大小的限制),所以综合以上情况,可以考虑使用 MP 的批量插入功能 。
来源:
https://mp.weixin.qq.com/s/HzT6G9x6fb4hPZqkBvTIew

【MyBatis 批量插入数据的 3 种方法!】


推荐阅读