批量操作是通过一次数据库交互执行多条 SQL 的数据处理方式,核心价值是减少应用与数据库的网络 IO 次数,大幅提升大数据量的写入 / 更新 / 删除性能。
MyBatis Plus 提供两套批量操作方案:
基础批量:saveBatch/updateBatchById(低版本支持,底层循环单条执行)
高级批量:MybatisBatch/MybatisBatchUtils(3.5.4+ 版本支持,底层执行真正的批量 SQL,性能最优)
极致性能:真正的批量 SQL 执行,性能是基础批量的 5~10 倍
功能全面:支持插入、更新、删除、自定义 Mapper 方法、批量 saveOrUpdate
灵活兼容:支持 Spring/ 非 Spring 环境,兼容所有数据库
结果可查:返回 BatchResult 批量执行结果,便于业务校验
事务安全:完美支持 Spring 事务管理
无侵入:无需修改原有 Mapper/Service 代码
核心版本:MyBatis Plus 3.5.4 +
必须注入:SqlSessionFactory(Spring 容器自动管理)
基础依赖:mybatis-plus-boot-starter
数据库:支持 MySQL、Oracle、PostgreSQL 等主流数据库
高级批量操作基于 3 个核心类实现,位于包 com.baomidou.mybatisplus.core.batch:
// 批量插入
method.insert()
// 根据 ID 批量更新
method.updateById()
// 自定义 Mapper 方法
method.get("自定义方法名", 参数转换器)List<BatchResult>:按 SQL 类型分组返回执行结果,可统计成功条数。
注入 SqlSessionFactory
准备批量数据列表
通过 MybatisBatchUtils 静态调用执行批量操作
(可选)添加事务控制
@Autowired
private SqlSessionFactory sqlSessionFactory;静态工具类批量插入(推荐)
最简写法,无需手动创建对象
// 1. 准备 1000 条测试数据
List<H2User> userList = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
userList.add(new H2User("批量用户 " + i));
}
// 2. 静态工具类执行批量插入
List<BatchResult> results = MybatisBatchUtils.execute(
sqlSessionFactory,
userList,
new MybatisBatch.Method<>(H2UserMapper.class).insert()
);非实体类型批量插入
原始数据为 ID/ 普通类型,自动转换为实体
List<Long> idList = Arrays.asList(1001L, 1002L, 1003L);
MybatisBatchUtils.execute(
sqlSessionFactory,
idList,
new MybatisBatch.Method<>(H2UserMapper.class).insert(id -> {
// 数据类型转换:Long → H2User
H2User user = new H2User();
user.setId(id);
user.setName("转换用户 " + id);
return user;
})
);根据 ID 批量更新
List<H2User> updateList = new ArrayList<>();
H2User user1 = new H2User(1L, "更新名称 1");
H2User user2 = new H2User(2L, "更新名称 2");
updateList.add(user1);
updateList.add(user2);
MybatisBatchUtils.execute(
sqlSessionFactory,
updateList,
new MybatisBatch.Method<>(H2UserMapper.class).updateById()
);自定义 Mapper 方法批量执行
支持注解 /XML 自定义 SQL,无侵入
// Mapper 层自定义方法
@Insert("INSERT INTO h2_user(name, age) VALUES(#{name}, #{age})")
int insertUser(H2User user);
// 批量执行自定义方法
MybatisBatchUtils.execute(
sqlSessionFactory,
userList,
new MybatisBatch.Method<>(H2UserMapper.class).get("insertUser")
);批量 saveOrUpdate(存在更新,不存在插入)
MybatisBatchUtils.saveOrUpdate(
sqlSessionFactory,
userList,
// 插入方法
new MybatisBatch.Method<>(H2UserMapper.class).insert(),
// 判断逻辑:ID 不存在则插入
(sqlSession, user) -> userMapper.selectById(user.getId()) == null,
// 更新方法
new MybatisBatch.Method<>(H2UserMapper.class).updateById()
);批量操作必须开启事务,保证数据一致性,Spring 环境推荐 TransactionTemplate。
@Autowired
private TransactionTemplate transactionTemplate;
// 事务中执行批量操作
List<BatchResult> results = transactionTemplate.execute(status -> {
try {
return MybatisBatchUtils.execute(sqlSessionFactory, userList,
new MybatisBatch.Method<>(H2UserMapper.class).insert());
} catch (Exception e) {
// 异常回滚
status.setRollbackOnly();
throw new RuntimeException("批量插入失败", e);
}
});控制批次大小 每批次数据量建议 500~1000 条,避免数据包过大
关闭无需的特性 大数据量关闭自动填充、逻辑删除校验(非必要)
只读事务 仅查询场景使用 @Transactional(readOnly = true)
数据库级优化 超大数据量(千万级)使用数据库原生 LOAD DATA(MySQL):
LOAD DATA INFILE '/path/data.csv'
INTO TABLE h2_user
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;严禁循环调用批量方法 循环中频繁获取数据库连接,会导致性能急剧下降
SqlSessionFactory 必须注入 非 Spring 环境需手动初始化 MyBatis 并获取 SqlSessionFactory
异常处理 批量执行抛出 PersistenceException,需统一捕获
跨 SqlSession 问题 saveOrUpdate 跨会话时,需手动查询数据状态,避免缓存问题
不支持分页 批量操作仅用于全量数据处理,不结合分页使用
基础批量的坑 低版本 saveBatch 并非真正批量,大数据量严禁使用
MyBatis Plus 3.5.4+ 提供的 MybatisBatch 是真正高性能批量操作方案
核心价值:减少网络 IO,百万级数据处理性能提升 10 倍
支持场景:批量插入、更新、删除、自定义方法、saveOrUpdate
必须搭配事务使用,保证数据安全
静态工具类 MybatisBatchUtils 是企业开发首选,代码极简、易维护
大数据量优先选择高级批量,超大数据量使用数据库原生 LOAD DATA