先上代码
private boolean updateBatchByQueryWrapper(Collection<Route> entityList, Function<Route, QueryWrapper> queryWrapperFunction) {
String sqlStatement = this.getSqlStatement(SqlMethod.UPDATE);
System.out.println("sqlStatement = " + sqlStatement);
return this.executeBatch(entityList, DEFAULT_BATCH_SIZE, (sqlSession, entity) -> {
MapperMethod.ParamMap param = new MapperMethod.ParamMap();
param.put(Constants.ENTITY, entity);
param.put(Constants.WRAPPER, queryWrapperFunction.apply(entity));
System.out.println("sqlStatement = " + sqlStatement);
sqlSession.update(sqlStatement, param);
});
}
@Override
public void test() {
Route route = new Route();
route.setParentIndexes("1,2,3");
route.setProductId(955);
route.setId(378);
Route route2 = new Route();
route2.setParentIndexes("1,2");
route2.setId(379);
List<Route> list = new ArrayList<>(2);
list.add(route);list.add(route2);
this.updateBatchByQueryWrapper(list,route3->new QueryWrapper<>().eq("id",route3.getId()));
}
乍一看看感觉没问题,但是如果Route bean中有
@TableField(updateStrategy = FieldStrategy.IGNORED)
那么null值,直接更新了,这明显就出bug了,但是又不能取消,因为确实有场景要用。
查了相关资料,可用 on duplicate 也可以用 foreach 并开启&allowMultiQueries=true ,也可以自定义 SQL注入器扩展
结合老项目实际情况。选择foreach 上代码
<update id="updateBatch" parameterType="java.util.List">
<foreach collection="list" item="item" index="index" open="" close="" separator=";">
update route
<set>
parent_indexes=#{item.parentIndexes}
</set>
where id = ${item.id}
</foreach>
</update>
结果