java 8 stream 本身不直接支持分批入库,但可通过 intstream.range + groupingby 按索引分组实现切片,或借助 guava lists.partition、apache commons listutils.partition 等第三方工具优雅分批,再结合 jdbc 批处理、mybatis foreach 或 jpa 优化方式逐批入库,并需注意事务隔离与异常容错。

Java 8 的 Stream 本身不直接支持“分批入库”,但结合 Collectors.groupingBy 或自定义分块逻辑(如按索引分组),可以优雅地将大数据集切分为固定大小的批次,再逐批执行 JDBC 插入、MyBatis 批量插入或 JPA saveAll 等操作。关键在于:**分组是手段,分批才是目的;Stream 负责切片,业务逻辑负责入库。**
用 IntStream.range + groupingBy 按批次大小分组
这是最常用且清晰的方式:把原始列表转为带索引的流,按 index / batchSize 分组,每组即为一个批次。
List<user> users = ...;
int batchSize = 100;
Map<integer list>> batchMap = IntStream.range(0, users.size())
.boxed()
.collect(Collectors.groupingBy(
i -> i / batchSize,
Collectors.mapping(users::get, Collectors.toList())
));
batchMap.values().forEach(batch -> {
// 执行批量插入,例如:
// userRepository.saveAll(batch);
// 或 jdbcTemplate.batchUpdate(...);
});
</integer></user>
用 Guava 或 Apache Commons 实现更简洁的分块(推荐生产环境)
原生 Stream 缺乏 partition 操作,第三方库更直观。例如 Guava 的 Lists.partition:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
-
Guava 方式(无流式但更可读):
List<list>> batches = Lists.partition(users, 100);</list>
再遍历batches执行入库即可。 -
Apache Commons Collections:
List<list>> batches = ListUtils.partition(users, 100);</list>
这类方式避免了索引计算和中间 Map 构建,内存更友好,也更容易单元测试。
配合 JDBC 批处理提升入库性能
分批只是第一步,真正高效依赖底层批量执行:
- 使用
JdbcTemplate.batchUpdate,传入batchSize对应的参数列表; - MyBatis 中开启
useGeneratedKeys=false并用<foreach></foreach>构建批量 INSERT; - JPA 中慎用
saveAll(默认逐条),建议切换为EntityManager+ 手动 flush + clear,或改用 Hibernate 的StatelessSession。
注意事务与异常处理
单批次失败不应导致整批回滚(除非业务强一致要求),建议:
- 每个批次在独立事务中执行(如 Spring
@Transactional(propagation = Propagation.REQUIRES_NEW)); - 捕获批次级异常,记录失败批次数据和原因,支持重试或人工干预;
- 避免长事务锁表,尤其在高并发写入场景下。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










