Spring JPA如何批量更新多行数据且id不存在时不新增记录
最优实现方案
核心思路
先批量校验ID存在性,过滤掉数据库中无对应ID的记录后再执行更新操作,全程使用批量处理保证性能,避免单条操作带来的过多数据库IO损耗。
具体实现步骤(以Spring Data JPA技术栈为例)
- 第一步:使用
ICsvBeanReader读取CSV所有行数据,转换为对应实体类的列表,同时提取所有行的id存入csvIdList集合 - 第二步:调用
findAllById(csvIdList)方法批量查询数据库中已存在的ID对应的实体,同时将这些存在的ID存入existIdSet集合 - 第三步:过滤CSV读取得到的实体列表,仅保留ID在
existIdSet中的记录,将需要更新的字段(quantity、name)覆盖到从数据库查询得到的对应实体对象上 - 第四步:调用
saveAll()方法保存更新后的实体列表,此时列表中所有实体的ID都已在数据库存在,不会触发新增逻辑
大数据量场景优化
如果CSV行数超过1000条,建议做分批处理:
- 每次读取100~500行CSV作为一批,按上述逻辑处理完一批再处理下一批,避免内存占用过高
- 追求更高性能可以直接使用自定义JPQL批量更新,不需要先查询实体,示例代码如下:
// 对应你的Repository层接口方法 @Modifying @Query("update 你的实体类名 g set g.quantity = :quantity, g.name = :name where g.id = :id") int updateIfExists(@Param("id") Long id, @Param("quantity") int quantity, @Param("name") String name);
配合JPA批量执行配置,直接调用该方法即可,方法返回值为0就代表对应ID不存在,自动忽略即可。
注意事项
- 整个更新过程建议加事务控制,避免部分更新成功部分失败导致的数据不一致问题
- 若CSV数据量达十万条以上,建议直接使用JDBC批量更新API,性能比JPA更优
内容的提问来源于stack exchange,提问作者java dev
相关产品推荐
相关产品推荐

