说明
在开发的过程中,有时候想要批量 update 数据库中的一批数据,有很多种方案,常见有手动提交事务、手动编写批量更新的 SQL 语句。
下面说明一下使用手动编写拼接 SQL 语句的方式。
例如:example 表中有下面这些字段。
id(主键)、update_time、name、age
java 中定义的实例类
private Long id;
private Date updateTime;
private String name;
private Integer age;
Mapper 中定义的 SQL 批量更新语句
@Update(" <script>" +
" UPDATE example" +
" SET" +
" update_time=CASE id" +
" <foreach collection=\"list\" item=\"item\" index=\"index\">" +
" <choose>" +
" <when test='item.updateTime!=null'>" +
" WHEN ${item.id} THEN #{item.updateTime}" +
" </when>" +
" <otherwise>" +
" WHEN ${item.id} THEN #{item.update_time}" +
" </otherwise>" +
" </choose>" +
" </foreach>" +
" END" +
" ,name= CASE id" +
" <foreach collection=\"list\" item=\"item\" index=\"index\">" +
" <choose>" +
" <when test='item.name!=null'>" +
" WHEN ${item.docId} THEN #{item.name}" +
" </when>" +
" <otherwise>" +
" WHEN ${item.docId} THEN name" +
" </otherwise>" +
" </choose>" +
" </foreach>" +
" END" +
" ,execute_id = CASE id" +
" <foreach collection=\"list\" item=\"item\" index=\"index\">" +
" <choose>" +
" <when test='item.age!=null'>" +
" WHEN ${item.id} THEN #{item.age}" +
" </when>" +
" <otherwise>" +
" WHEN ${item.age} THEN age" +
" </otherwise>" +
" </choose>" +
" </foreach>" +
" END" +
" WHERE doc_id IN " +
" <foreach collection = 'list' item='item' open='(' close=')' separator=',' > " +
" ${item.id}" +
" </foreach>" +
" </script>")
void updateDataBatch(
@Param(value = "list") List<UserEntity> userList);
注意点
该更新语句会更新 where 条件中的所有符合条件的行。
如果使用下面的写法
" update_time=CASE id" +
" <foreach collection=\"list\" item=\"item\" index=\"index\">" +
" <if test='item.updateTime!=null'>" +
" WHEN ${item.id} THEN #{item.updateTime}" +
" </if>" +
" </foreach>" +
" END" +
则匹配到对应 id 的数据会更新 updateTime 字段,其他符合 where 条件的行中的 updateTime 字段都会置为 NULL。
如果想要实现:
只要某个字段指定了 CASE WHEN 语句,那么符合 WHERE 条件的行,都要指定该字段对应的值,如果不赋新值,就使用旧值。
可以使用上面Mapper 中定义的 SQL 批量更新语句的写法。
也可以使用下面的写法:
" update_time=CASE id" +
" WHEN ${item.id} THEN #{item.updateTime}" +
" else" +
" now()" +
" END" +
针对符合 where 条件中的数据行中,指定 id 的行的 updateTime 设置为指定值,其他行设置为当前时间。