839 字
约 2 分钟
7
S08-J04 · 批量操作与 SQL 注入器

适用读者:用 for 循环插过一万条数据的人。
前置:S08-B04。
覆盖旧文:903(82) 1181(99) 375(366) + 空壳 1147 补写(E-S08-014)= 547 点。
上一篇:S08-J03 · 缓存:一级/二级与失效
下一篇:S08-A01 · 分库分表。


1. 一句话结论

批量插入的性能差异不在"SQL 好不好",在"网络往返次数":一万次 insert = 一万次往返;一条多值 insert = 一次。

方式 SQL 次数 往返
循环 insert N 次 N 次
MyBatis ExecutorType.BATCH N 次(攒批发送) 分批
一条 insert ... values (...),(...) 1 次 1 次
MP saveBatch 底层用 BATCH executor 分批

实测(S08-B01 的 Executor 对照):executor-type: batch 会把多条 DML 攒到 flushStatements 才发。


2. 三种批量写法

2.1 多值 INSERT(最快)

<insert id="batchInsert">
  insert into sys_user(user_name, age) values
  <foreach collection="list" item="u" separator=",">
    (#{u.userName}, #{u.age})
  </foreach>
</insert>

注意:单条 SQL 太长会撞 max_allowed_packet(MySQL),要分批(如 500 条/批)。

2.2 ExecutorType.BATCH

SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
优点 缺点
内存友好(分批发) 无法拿到每条的自增 ID(除非 JDBC 支持)
适合海量插入 出错时定位困难

2.3 MP saveBatch

userMapper.insertBatchSomeColumn(list);   // 需自定义
// 或 service.saveBatch(list, 500);

本质:循环 + BATCH executor。不是"一条 SQL"——要一条 SQL 得自己写 XML。


3. SQL 注入器(A-375,366 点)

MP 的"注入器"不是"SQL 注入漏洞",是"把方法注入到 Mapper"(名字容易吓人)。

public class MyInsertMethod extends AbstractMethod {
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo info) {
        // 生成一条自定义 SQL 的 MappedStatement
    }
}
用途 说明
加自定义通用方法 如 insertBatchSomeColumn(真正的多值插入)
减少重复 XML 一次定义,所有 Mapper 可用

判据:"这个 SQL 会在 5 个以上 Mapper 里重复吗?" 会 → 注入器;不会 → XML 更快。


4. 批量的四个注意点

点 说明
事务大小 太大 → 锁等待/回滚日志膨胀
分批大小 500–1000 条/批常见
唯一键冲突 整批失败 or 逐条跳过(INSERT IGNORE/ON DUPLICATE)
自增 ID 回填 BATCH 模式下可能拿不到

5. 五个误区

误区 真相
"saveBatch 是一条 SQL" 是循环 + 批处理
"批越大越快" 受 packet/事务/锁限制
"SQL 注入器是漏洞" 是 MP 的扩展机制
"BATCH 能拿到所有自增 ID" 不一定
"循环 insert 也行" 网络往返是主要成本

6. 自检

  1. 三种批量方式的 SQL 次数差异?
  2. 多值 insert 的批量大小受什么限制?
  3. ExecutorType.BATCH 的代价是什么?
  4. MP 的"SQL 注入器"到底是什么?
  5. 批处理为什么要注意事务大小?

7. 下一篇

S08-A01 · 分库分表:为什么、怎么分、带来什么

进阶层结束,架构师层开始:单表多大该分、分片键怎么选、分完之后的五个新问题。


本篇属于系列《S08 · MyBatis 持久层》。旧文来源:A-903/1181/375(空壳 1147 补写)。

S08-J04 · 批量操作与 SQL 注入器
https://www.clxhxhhr.top/posts/5290/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。