开发者

MyBatis使用CASE WHEN进行批量更新的高效写法

目录
  • 一、为什么要用 CASE WHEN 批量更新?
  • 二、示例场景
  • 三、MyBATis 批量更新写法(CASE WHEN)
  • 四、SQL 生成效果展示
  • 五、WHERE IN 的作用(非常关键!)
  • 六、性能对比
  • 七、可维护性优化方案
  • 八、使用建议与限制
  • 九、总结
  • 结语

在实际业务开发中,我们经常需js批量更新多条数据

最常见的做法是:

for (Item item : list) {
    mapper.update(item);
}

但这样会执行多次 SQL,性能低下,尤其当更新上百条数据时,数据库压力很大。

有没有更高效的方式?

有!可以使用 SQL 的 CASE WHEN 批量更新写法

一、为什么要用 CASE WHEN 批量更新?

传统循环更新的缺点:

  • 每次执行一条 UPDATE,频繁网络 IO。
  • MyBatis 多次 prepare statement,效率低。
  • 数据量大时,明显拖慢系统性能。

CASE WHEN 批量更新的优点:

  • 一次 SQL 完成多条更新;
  • 性能提升明显(尤其在上百条数据时);
  • 减少数据库交互次数;
  • 兼容 MyBatisXufjop 动态 SQL,非常灵活。

二、示例场景

假设我们有一张表:

CREATE TABLE erp_product_identity (
  id BIGINT PRIMARY KEY,
  identity_code VARCHAR(50) UNIQUE,
  product_id BIGINT,
  warehouse_id BIGINT,
  update_time DATETIME
);

我们现在有一个 list,需要根据 identity_code 批量更新对应的 product_idwarehouse_id

三、MyBatis 批量更新写法(CASE WHEN)

以下是完整的 MyBatis XML 写法:

<update id="batchUpdateProductIdentityCase">
  UPDATE erp_product_identity
  <set>
    product_id = CASE identity_code
      <foreach collection="list" item="item">
        WHEN #{item.identityCode} THEN #{item.productId}
      </foreach>
    END,
    warehouse_id = CASE identity_code
      <foreach collection="list" item="item">
        WHEN #{item.identityCode} THEN #{item.warehouseId}
      </foreach>
    END,
    update_time = NOW()
  </set>
编程客栈  WHERE identity_code IN
  <foreach collection="list" item="item" open="(" separator="," close=")">
    #{item.identityCode}
  </foreach>
</update>

四、SQL 生成效果展示

当传入 3 条记录时:

list = [
  { identityCode: 'A001', productId: 11, warehouseId: 101 },
  { identityCode: 'A002', productId: 22, warehouseId: 102 },
  { identityCode: 'A003', productId: 33, warehouseId: 103 }
];

最终生成的 SQL 如下:

UPDATE erp_product_identity
SET
  product_id = CASE identity_code
    WHEN 'A001' THEN 11
    WHEN 'A002' THEN 22
    WHEN 'A003' THEN 33
  END,
  warehouse_id = CASE identity_code
    WHEN 'A001' THEN 101
    WHEN 'A002' THEN 102
    WHEN 'A003' THEN 103
  END,
  update_time = NOW()
WHERE identity_code IN ('A001', 'A002', 'A003');

一次 SQL 更新三条数据。

效率远高于逐条执行!

五、WHERE IN 的作用(非常关键!)

有些人看到这行:

WHERE identity_code IN (...)

可能会问:这不是多余的吗?

其实它是 必须的

没有这个条件,数据库会对整张表执行 UPDATE

未命中的记录的 CASE WHEN 结果是 NULL,导致字段被更新成 NULL,数据直接“报废”。

所以必须加上 WHERE identity_code IN (...) 来限制更新范围。

六、性能对比

更新方式SQL 执行次数性能(1000 条)备注
循环单条更新1000 次每次一条 SQL
MyBatis 批量更新(CASE WHEN)1 次一次 SQL 搞定
MyBatis 批量更新(foreach 多值)中等⚡ 一般取决于实现逻辑

推荐场景

当你要批量更新几十到几百条数据(上千条以内)时,CASE WHEN 是最优解。

七、可维护性优化方案

为了可读性更高,可以把 CASE 部分封装成单独 SQL 片段:

<sql id="caseProductId">
  product_id = CASE identity_code
    <foreach collection="list" item="item">
      WHEN #{item.identityCode} THEN #{item.productId}
    </foreach>
  END
</sql>

<sql id="caseWarehouseId">
  warehouse_id = CASE identity_code
    <foreach collection="list" item="item">
      WHEN #{item.identityCode} THEN #{item.warehouseId}
    </forejavascriptach>
  END
</sql>

<update id="batchUpdateProductIdentityCase">
  UPDATE erp_product_identity
  <set>
    <include refid="caseProductId"/>
    ,
    <include refid="caseWarehouseId"/>
    ,
    update_time = NOW()
  </set>
  WHERE identity_code IN
  <foreach collection="list" item="item" open="(" separator="," close=")">
    #{item.identityCode}
  </foreach>
</update>

这样结构更清晰、维护更方便。

八、使用建议与限制

项目建议 / 限制
identity_code必须是唯一键或主键
批量数量推荐单次 ≤ 1000 条
SQL 长度mysql 默认最大 1MB,可通过 max_allowed_packet 调整
时间字段可以统一 update_time = NOW()
数据库适用于 MySQL、PostgreSQL、SQL Server

九、总结

优点缺点
批量更新性能高SQL 长度可编程客栈能受限
一次执行减少数据库压力可读性稍弱
兼容 MyBatis 动态 SQL仅适合根据主键或唯一字段更新

结语

CASE WHEN 批量更新写法,是 MyBatis 开发中非常实用的一种性能优化技巧。

在日常项目中,当需要 根据不同条件批量更新不同字段值 时,它几乎是最优方案。

 一条 SQL,解决多条更新,让你的系统更快、更稳、更优雅。

以上就是MyBatis使用CASE WHEN进行批量更新的高效写法的详细内容,更多关于MyBatis CASE WHEN批量更新的资料请关注编程客栈(www.devze.com)其它相关文章!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新开发

开发排行榜