批量更新数据:Mybatis update foreach 和 update case when 写法及比较

发布于:2025-09-13 ⋅ 阅读:(13) ⋅ 点赞:(0)

        在平常的开发工作中,我们经常需要批量更新数据,业务需要每次批量更新几千条数据,采用 update foreach 写法的时候,接口响应 10s 左右,优化后,采用 update ... case when 写法,接口响应 2s 左右。今天来总结一下两种常见的写法使用场景及性能比较。

一:foreach 批量更新

<update id="batchUpdateStudentScore">
    <foreach collection="list" item="item" separator=";">
        UPDATE student_score
        SET score = #{item.score}, grade = #{item.grade}  <!-- 修复原写法的语法错误 -->
        WHERE id = #{item.id}
    </foreach>
</update>

        生成的执行sql如下:

UPDATE student_score SET score = 85, grade = 'A' WHERE id = 1;
UPDATE student_score SET score = 70, grade = 'B' WHERE id = 2;
UPDATE student_score SET score = 95, grade = 'A+' WHERE id = 3;

二:update ... case when 批量更新

<update id="batchUpdateStudentScore">
    UPDATE student_score
    SET 
      score = CASE 
        <foreach collection="list" item="item" separator="">
            WHEN id = #{item.id} THEN #{item.score}
        </foreach>
        ELSE score 
      END,
      grade = CASE 
        <foreach collection="list" item="item" separator="">
            WHEN id = #{item.id} THEN #{item.grade}
        </foreach>
        ELSE grade 
      END
    WHERE id IN 
      <foreach collection="list" item="item" open="(" separator="," close=")">
          #{item.id}
      </foreach>
</update>

        生成的执行sql如下:

UPDATE student_score
SET 
  score = CASE 
    WHEN id = 1 THEN 85 
    WHEN id = 2 THEN 70 
    WHEN id = 3 THEN 95 
    ELSE score 
  END,
  grade = CASE 
    WHEN id = 1 THEN 'A' 
    WHEN id = 2 THEN 'B' 
    WHEN id = 3 THEN 'A+' 
    ELSE grade 
  END
WHERE id IN (1, 2, 3);

三:对比总结

维度

foreach批量更新

UPDATE ... CASE WHEN批量更新

SQL 语句数量

N 条(N = 列表长度)

1 条

数据库交互次数

N 次

1 次

原子性 依赖事务 天然原子性
适用数据量 50 条 50 条 - 5000 条,数量量超过 1000 时建议分批

网络传输量

大(多次传输 SQL)

小(单次传输长 SQL)

  总结:foreach 本质都是循环执行多条 SQL,效率远低于 case when,当一次批量更新的数据大于10条时,建议采用 case when 写法。

 四:使用场景

1:foreach 批量更新适用场景

        a:如单次更新 10 条以内,循环的性能损耗可忽略。

        b:每条记录更新需单独控制事务(如某条失败不影响其他)。

        注意:需确保数据库连接池允许批量执行多条 SQL(如 MySQL 需开启allowMultiQueries=true)。数据量过大(如 N>1000)可能导致连接超时或 SQL 注入风险增加。

2. update...case when 适用场景

        a:单次更新 50-1000 条,需减少数据库交互次数。

        b:仅需根据主键(id)匹配更新值,无需额外计算。

        c:同时更新多个字段时,case when 比  foreach 更简洁高效。

        注意:必须加 where id in (...),否则会全表扫描(未匹配记录会被ELSE保持原值,但浪费性能)。若 N>1000,生成的 SQL 可能过长,建议分批次(如每 500 条一批)。

五:总结

        数据量小于 50 条时,优先采用 update foreach,写法简单,性能也可以。当大于 50 条,甚至上千条时,采用 update...case when 写法,执行效率高,比 update foreach 写法性能提升几倍。但是如果一次更新几千条数据,建议分批执行,比如每500条执行一次。