网站首页 > 技术文章 正文
你还在用for循环做MyBatis批量插入? 本文通过真实案例+代码实测,对比三种批量插入方案的速度差异与实现原理。文末附实测数据截图,看完立省80%数据库操作时间!
一、青铜方案:循环单条插入(性能灾难)
// 典型错误示例
for (User user : userList) {
userMapper.insert(user);
}
特点:
- 每条insert语句单独执行
- 每次请求都经历完整JDBC流程
- 事务自动提交(除非手动控制)
实测结果(1万条数据):
- 耗时:约30秒
- 优点:代码简单
- 缺点:产生1万次网络IO,99%的时间浪费在连接开销
二、白银方案:BatchExecutor批处理(性能提升10倍)
// 开启批处理模式
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
for (User user : userList) {
mapper.insert(user);
if(i % 1000 == 0){
sqlSession.flushStatements(); // 分段提交
}
}
sqlSession.commit();
核心原理:
- 通过ExecutorType.BATCH启用JDBC批处理
- 将多个SQL语句打包发送
- 事务统一提交
实测结果(1万条数据):
- 耗时:约3秒
- 优点:JDBC层优化,网络IO减少90%
- 缺点:需要手动控制提交时机
三、王者方案:动态SQL拼接(极限性能)
<!-- XML动态SQL -->
<insert id="batchInsert">
INSERT INTO user (name,age) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.name}, #{item.age})
</foreach>
</insert>
执行特点:
- 生成单条INSERT INTO ... VALUES (...),(...)语句
- 数据库单次解析执行
- 利用数据库批量写入优化
实测结果(1万条数据):
- 耗时:约1秒
- 优点:理论最快执行方式
- 致命缺陷:SQL长度限制(MySQL默认4MB)
全方位对比表
维度 | 循环单条插入 | BatchExecutor | 动态SQL拼接 |
执行方式 | N条独立SQL | JDBC批处理 | 单条大SQL |
网络IO次数 | N次 | 1次 | 1次 |
事务控制 | 自动提交 | 手动提交 | 单事务 |
内存消耗 | 低 | 中 | 高(SQL缓存) |
可读性 | ★★★★ | ★★★ | ★★ |
适用场景 | <100条 | 1k-10w级 | <5k条(防溢出) |
实测数据验证(1万条记录)
避坑指南
- 动态SQL长度陷阱:MySQL的max_allowed_packet参数限制单条SQL大小
- 批处理内存溢出:每5千条左右建议执行flushStatements()
- 事务一致性:BatchExecutor必须显式commit才会生效
- 主键回写:动态SQL方案无法获取全部自增ID
选型建议
- 小数据量(<500条):动态SQL方案最优
- 常规批量(1k-5w条):BatchExecutor最稳妥
- 超大数据量(>10w条):结合BatchExecutor+分段提交
终极技巧:生产环境推荐组合方案:BatchExecutor + 分批次提交 + 动态SQL长度控制,实测可提升百倍性能!
思考题:为什么动态SQL方案在Oracle数据库中反而可能变慢?欢迎评论区讨论!(提示:与SQL解析机制有关)
猜你喜欢
- 2025-07-27 [JPA教程]02.认识JPA的注解.md(jpa的@query注解)
- 2025-07-27 MyBatis配置详解:从入门到精通(mybatis配置文件详解)
- 2025-07-27 Mybatis Plus框架学习指南-第三节内容
- 2025-07-27 什么是实时数据同步?纯干货解读!(什么是实时数据传输)
- 2025-07-27 Mybatis Plus框架学习指南-第八节内容(常用的注解)
- 2024-10-27 一文看懂mycat配置--数据库的读写分离、分表分库
- 2024-10-27 基于Percona XtraBackup 实现全备&增量备份与恢复
- 2024-10-27 Java EE核心框架实战:如何使用MyBatis实现CURD-2种数据库
- 2024-10-27 mysql如何进行累加计算 mysql 变量累加
- 2024-10-27 Springboot集成Mybatis ID生成策略注解 @GeneratedValue
你 发表评论:
欢迎- 633℃几个Oracle空值处理函数 oracle处理null值的函数
- 626℃Oracle分析函数之Lag和Lead()使用
- 614℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 608℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 606℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 599℃【数据统计分析】详解Oracle分组函数之CUBE
- 588℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 574℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
-
- CVE-2025-30762|Oracle(java oracle)
- 低代码可能铲不掉“屎山”,但能让这个它更有「型」
- 科技大事件:新苹果手表可通过击掌或握手来传递信息
- 你的百万级上下文窗口大模型,可能并没有你想象中那么强
- DApp 开发中的安全测试(软件测试过程中安全测试的具体应用场景和测试思路)
- 盘点Java中最没用的知识⑧:这3个过时套路,你还在代码里硬撑?
- 机房硬件设备及Oracle数据库软件维护服务项目竞争性磋商公告
- 微软与甲骨文扩大合作关系,推出Oracle Database@Azure
- JPA实体类注解,看这篇就全会了(java实体类注解)
- Java反射机制最全详解(图文全面总结)
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- 前端获取当前时间 (50)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (80)
- oracle 工具 (55)
- oracle 内存 (55)
- oracle 导出表 (62)
- oracle约束 (54)
- oracle 中文 (51)
- oracle链接 (54)
- oracle的函数 (58)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)