Mybatis批量更新优化方案

文章介绍了在对接客户接口时遇到的数据同步问题,原方案使用MyBatis-Plus的saveOrUpdateBatch方法性能不佳。随后提出了两种优化方案:一是使用foreach标签拼接多条SQL进行批量更新,二是结合casewhen语句生成更高效的单条SQL。经过测试,优化方案二在数据量不大时表现最优,耗时仅为131ms。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

今天在对接客户接口的时候,对方同步数据到我们系统,涉及到数据批量更新,插入的逻辑,出于性能方面的考虑,决定对自己写的逻辑进行优化,下面对几种优化方案进行总结。

需求

同步部门数据到mysql数据库,响应示例:

在这里插入图片描述
拿到json后,如果数据库不存在部门数据,则进行插入操作;存在部门数据,则做修改操作。这里演示存在数据进行修改操作。

原方案

使用mybatis-plus的saveOrUpdateBatch接口

修改部分代码逻辑:
在这里插入图片描述

启动项目进行测试:

在这里插入图片描述

经测试,接收的数据30条左右,耗时 1082ms ,显然达不到预期的性能要求,于是针对此进行优化。

优化方案一

在mybatis的xml文件中,使用foreach标签来拼接SQL语句。

代码示例:

    <update id="updateBatchById">
        <foreach collection="list" item="item" separator=";">
            update
            `sys_dept`
            set
            `DEPT_NAME` = #{item.deptName},
            `DEPT_CODE` = #{item.deptCode},
            `PARENT_ID` = #{item.parentId}
            where
            dept_id = #{item.deptId}
        </foreach>
    </update>

mapper层:

    /**
     * 批量更新
     * @param list
     */
    void updateBatchById(@Param("list") List<SysDept> list);

然后在修改数据的逻辑中,直接调用mapper的接口

在这里插入图片描述

重启项目,再次测试:

在这里插入图片描述

可以看到,同样的数据,这个方案耗时273ms

优化方案二

foreach标签配合case when拼接SQL语句。

代码示例:

<update id="batchUpdate" parameterType="java.util.List">
        update sys_dept
        <trim prefix="set" suffixOverrides=",">
            <trim prefix=" `DEPT_NAME` = case " suffix=" end, ">
                <foreach collection="list" item="item">
                    <if test="item.deptName != null">
                        when dept_id = #{item.deptId} then #{item.deptName}
                    </if>
                </foreach>
            </trim>
            <trim prefix=" `DEPT_CODE` = case " suffix=" end, ">
                <foreach collection="list" item="item">
                    <if test="item.deptCode != null">
                        when dept_id = #{item.deptId} then #{item.deptCode}
                    </if>
                </foreach>
            </trim>
            <trim prefix=" `PARENT_ID` = case " suffix=" end, ">
                <foreach collection="list" item="item">
                    <if test="item.parentId != null">
                        when dept_id = #{item.deptId} then #{item.parentId}
                    </if>
                </foreach>
            </trim>
        </trim>
        where
        dept_id in
        <foreach collection="list" item="item" open="(" close=")" separator=",">
            #{item.deptId}
        </foreach>
    </update>

mapper层:

    /**
     * 批量更新
     * @param list
     */
    void batchUpdate(@Param("list") List<SysDept> list);

修改逻辑处直接调用:

在这里插入图片描述
重启项目,再次测试:

在这里插入图片描述
可以看到,同样的数据,这个方案耗时131ms。

经过多次测试会发现,在本案例中,优化方案二性能略强于优化方案一

总结

使用mybatisplus的saveOrUpdateBatch操作效率极低,查看sql日志可以发现,实际上还是一条一条插入的,而且在插入之前还要查询数据库是否存在该数据,耗时很久,建议不要使用。优化方案一是多条sql语句,需要数据库执行多次修改操作,而优化方案二是一条sql语句,只需要数据库执行一次修改操作。在数据量不是特别大的情况下,优化方案二优于优化方案一。

在数据量不大的情况下,推荐使用方案二。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值