MyBatis批量插入性能优化核心是减少交互次数、复用预编译语句,需结合ExecutorType.BATCH执行器、rewriteBatchedStatements=true驱动参数及合理分批;仅用<foreach>拼长SQL非真正批量,中小量(≤500条)可选,大数据量必须分批+flush+commit。

MyBatis 批量插入性能优化的核心,是减少数据库交互次数、复用预编译语句、避免单条 SQL 的重复开销。不能只靠写个 <foreach> 就以为是“批量”——那只是拼长 SQL,不是真正意义上的批处理。
用 ExecutorType.BATCH 替代 foreach 拼接
这是 MyBatis 官方推荐、底层对接 JDBC addBatch() 的高效方式:
- SqlSession 必须显式创建为
ExecutorType.BATCH,不能依赖全局配置(否则影响普通查询) - Mapper 接口保持单条 insert 方法(如
insert(User user)),不加<foreach> - Java 层循环调用该方法,MyBatis 自动攒批;每 500–1000 条调用一次
sqlSession.flushStatements()防止内存堆积 - 最后统一
commit(),事务由你控制,粒度更清晰
配合 MySQL 驱动参数 rewriteBatchedStatements=true
这个参数是关键加速器,但常被忽略:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 仅对 MySQL 有效,在 JDBC URL 中添加:
?rewriteBatchedStatements=true - 开启后,JDBC 驱动会把多条
INSERT INTO ... VALUES (...)自动合并为一条底层 batch 指令,大幅提升吞吐 - 不加它,
ExecutorType.BATCH仍走多条独立请求,性能提升有限
中小批量(≤500 条)可选 foreach 多值插入
适合事务强一致、数据量不大、且需主键回填的场景:
立即学习“Java免费学习笔记(深入)”;
- SQL 写法示例:
INSERT INTO user(name,age) VALUES <foreach>(...)</foreach> - 必须设
useGeneratedKeys="false",否则自增主键无法正确返回 - 注意 MySQL 的
max_allowed_packet上限(默认 4MB),超长 SQL 会直接报错 - Oracle 不原生支持多值 INSERT,需改用
INSERT ALL或拆分
超大数据量(如百万级)要分批 + 控制资源
单一大事务风险高,容易锁表、OOM、回滚代价大:
- 将原始 List 拆成子批次(如每 500 条一组)
- 每组使用独立的 Batch SqlSession,执行完立即
close()和commit() - 可搭配线程池并发提交(注意数据库连接数上限和事务隔离级别冲突)
- 在循环中调用
sqlSession.clearCache(),释放一级缓存压力


















