如何通过MyBatis框架在Java项目中实现MySQL的批量插入优化?

P粉602998670

P粉602998670

2026-06-24

1008人浏览

原创

不配 rewritebatchedstatements=true,mybatis 的 批量插入性能最多只有理论值的 1/10;只用 executortype.batch 而不控制分批大小,容易 oom 或触发 mysql 的 max_allowed_packet 限制。

如何通过mybatis框架在java项目中实现mysql的批量插入优化?

直接上结论:不配 rewriteBatchedStatements=true,MyBatis 的 <foreach></foreach> 批量插入性能最多只有理论值的 1/10;只用 ExecutorType.BATCH 而不控制分批大小,容易 OOM 或触发 MySQL 的 max_allowed_packet 限制。

MyBatis 的 多值插入必须配合 rewriteBatchedStatements=true

很多人以为写个 <foreach></foreach> 就算批量了,其实只是把多条 INSERT 拼成一条 SQL 发过去。但 JDBC 驱动默认仍会把它拆成 N 条单语句执行——每条都走完整解析 + 权限校验 + 日志刷盘流程。

真正起效的前提是数据库连接 URL 显式开启批处理重写:

jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true&useSSL=false&serverTimezone=UTC

这个参数会让 MySQL JDBC 驱动在底层把形如 INSERT INTO t(a,b) VALUES (?,?),(?,?) 的语句,自动转换为更高效的内部批处理调用(类似 addBatch() + executeBatch()),跳过重复解析。

  • 不加该参数时,10 万条数据插入耗时约 30 秒(实测)
  • 加上后,同样数据降至 3–5 秒(取决于批次大小和硬件)
  • MySQL 8.0+ 驱动必须用 mysql-connector-java:8.0.33+,旧版对 rewrite 支持不完整

ExecutorType.BATCH 不等于“自动优化”,要手动 flush + 分批

ExecutorType.BATCH 是 MyBatis 层的缓存机制,它把所有 insert() 调用暂存在内存里,等你调 flushStatements() 才真正发给数据库。但它不会自动分片——如果你传入 10 万条记录,MyBatis 会尝试一次性缓存全部,极易触发 JVM OOM 或 MySQL 报错 Packets larger than max_allowed_packet are not allowed

正确做法是边插入、边分批刷新:

Java JDK 25
Java JDK 25

Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。

下载
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int batchSize = 1000;
for (int i = 0; i 
  • batchSize 建议设为 500–2000,具体看单条数据体积(如含大文本字段则往小调)
  • 必须调用 flushStatements(),仅 commit() 不够——后者只触发事务提交,不强制发送缓冲 SQL
  • clearCache() 不可省略,否则一级缓存持续增长,GC 压力陡增

MyBatis XML 中 的写法细节决定成败

即使开了 rewriteBatchedStatements=true,XML 里拼 SQL 的方式也影响最终是否能走批处理路径。关键点在于:必须生成单条含多 VALUES 的 INSERT,不能拼出多个 INSERT 语句。

✅ 正确(一条 SQL,多组 VALUES):

<insert id="batchInsert">
  INSERT INTO user (username, email) VALUES
  <foreach collection="list" item="u" separator=",">
    (#{u.username}, #{u.email})
  </foreach></insert>

❌ 错误(拼出多条 INSERT,驱动无法合并):

<insert id="badBatchInsert"><foreach collection="list" item="u" separator=";">
    INSERT INTO user (username, email) VALUES (#{u.username}, #{u.email})
  </foreach></insert>
  • separator="," 是核心,确保最终生成的是 VALUES (..),(..),(..)
  • 不要用 separator=";" 或空格换行拼多条 INSERT,MySQL 不支持分号分隔的批量语句(除非用存储过程)
  • 若表有自增主键且需返回 ID,<foreach></foreach> 方式无法获取每条的 id,此时只能退回到 ExecutorType.BATCH + 单条插入模式

最容易被忽略的三个硬性依赖

上面所有优化都建立在三个底层条件满足的前提下,缺一不可:

  • MySQL 服务端必须用 innodb 引擎(MyISAM 不支持事务级批处理)
  • JDBC 连接池(如 HikariCP)要禁用自动提交:autoCommit=false,否则每次 insert() 都隐式 commit,彻底废掉批处理
  • 事务边界要显式控制:要么用 @Transactional 包裹整个方法,要么像上面示例一样手动 commit()/rollback(),否则可能卡在未提交状态

这些不是“可选配置”,而是批处理生效的开关。漏掉任意一个,你看到的都是“写了批量代码,跑起来还是逐条慢”。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

3716

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

2752

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

2777

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

635

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

600

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

705

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1268

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

18824

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

646

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 123人学习

使用phpenv集成环境安装极致CMS
使用phpenv集成环境安装极致CMS

共2课时 | 221人学习

phpEnv手册
phpEnv手册

共0课时 | 0人学习