MyBatis批量插入提效核心在于三层协同:启用ExecutorType.BATCH复用PreparedStatement、MySQL配置rewriteBatchedStatements=true驱动级合并SQL、合理分批(500–1000条/批)并调用flushStatements(),同时关闭自动提交、禁用useGeneratedKeys。

MyBatis 批量插入提效的核心,不是拼一条超长 SQL,而是让多条 insert 真正“批量发出去”——复用 PreparedStatement、减少网络往返、合并事务提交。关键在 JDBC 层、MyBatis 执行器、SQL 写法三层协同。
启用 BATCH 执行器模式
这是最基础也最关键的一步。默认 ExecutorType 是 SIMPLE,每次 insert 都新建 Statement;改用 BATCH 后,MyBatis 会缓存多条 SQL 到同一个 PreparedStatement,最后统一执行 executeBatch()。
- 代码中显式开启:SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)
- 或全局配置(推荐):
<setting name="defaultExecutorType" value="BATCH"/> - 必须手动调用 sqlSession.commit(),否则数据不落库
- 务必关闭自动提交:sqlSession.setAutoCommit(false)
配置 JDBC 驱动级批量优化(MySQL 必配)
仅开 MyBatis BATCH 不够——MySQL 官方驱动默认把 batch 拆成单条执行。需在数据库连接 URL 中启用重写:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 添加参数:rewriteBatchedStatements=true
- 完整示例:
jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true - 效果:驱动自动将 100 条 INSERT 合并为一条多值语句,性能可提升数倍
合理分批 + 及时 flush
万级数据不能一次性传入,否则易 OOM 或触发 MySQL 的 max_allowed_packet 限制。
立即学习“Java免费学习笔记(深入)”;
- 建议每 500~1000 条 调用一次 sqlSession.flushStatements()
- 大列表先按批次拆分,例如 10 万条 → 每批 1000 条,循环处理
- 配合设置
<setting name="jdbc.batch_size" value="1000"/>,控制内部攒批阈值
慎用 <foreach> 拼接多值 INSERT
<foreach> 适合中小批量(≤500 条)、事务强一致场景,但有明显限制:
- MySQL 支持,Oracle / PostgreSQL 不原生支持多值 INSERT
- 必须设
useGeneratedKeys="false",否则主键回填失效 - SQL 字符串过长易报错,需检查并调大
max_allowed_packet - XML 中
VALUES后不要换行或空格过多,避免生成非法 SQL

















