Mysql
主页 > 数据库 > Mysql >

MYSQL批量UPDATE的两种方式介绍

2024-11-16 | 佚名 | 点击:

工作中遇到批量更新的场景其实是比较常见的。
但是该如何正确的进行批量UPDATE,很多时候往往有点头大。
这里列2种可用的方式,供选择(请选择方式一,手动狗头。)。

如果使用了MyBatis增强组件MyBatisPlus,可以参考官网给出的解决方式(updateBatchById),或者自己查一下。

批量UPDATE方式一:SQL内foreach

举个????

1

2

3

4

5

6

7

8

9

<update id="updateUserForBatch" parameterType="com.bees.srx.entity.UserEntity">

    <foreach collection="list" item="entity" separator=";">

        UPDATE sys_user

        SET password=#{entity.password},age=#{entity.age}

        <where>

            id = #{entity.id}

        </where>

    </foreach>

</update>

这样写,肯定比 在业务方法中for循环单条update的效率是要高的。
但是如果遇到大批量的更新动作,可能也会产生效率低下的问题。
原因是SQL内的foreach本质上还是循环插入每一条数据,会产生 list.size() 个单条插入的独立SQL语句,每一条 UPDATE 语句都会被单独发送到数据库服务器执行。
这意味着如果列表中有100个元素,就会产生100次数据库往返通信。
这种方式不仅效率低下,而且对于大型批处理操作来说,可能会导致性能瓶颈和资源浪费。

优化:通过JDBC批处理通过 MyBatis 的 SqlSession 提供的批处理功能来手动执行批量更新。

1

2

3

4

5

6

7

try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {

    UserMapper mapper = session.getMapper(UserMapper.class);

    for (UserEntity user : userList) {

        mapper.updateUser(user);

    }

    session.commit();

}

这里mapper.updateUser就是单条的UPDATE语句。

通过这种方式,MyBatis 会在内存中积累所有的更新命令,然后在调用session.commit() 时一次性提交给数据库,这比逐条执行要高效得多。

注意:是否存在效率差异,未实践过!!!可能存在误人子弟的嫌疑。

批量UPDATE方式二:INSERT + ON DUPLICATE KEY UPDATE

1

2

3

4

5

6

7

8

9

10

11

<update id="updateForBatch" parameterType="com.bees.srx.entity.UserEntity">

    insert into sys_user

    (id,username,password) values

    <foreach collection="list" index="index" item="item" separator=",">

        (#{item.id},

        #{item.username},

        #{item.password})

    </foreach>

    ON DUPLICATE KEY UPDATE

     password=values(password)

</update>

不建议使用。要求较多,而且容易出现死锁。

注意事项

总结:

建议使用方式一,或者其优化方式(JDBC批处理)。

原文链接:
相关文章
最新更新