0


mybatis批量更新

参考:
mybatis批量更新

https://blog.csdn.net/qq_16992475/article/details/139633631

https://blog.csdn.net/zk673820543/article/details/106579809/

记得修改配置,增加rewriteBatchedStatements=true

datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
        # 主库数据源
        master:
            url: jdbc:mysql://xxx:3306/xxx?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=true
            username: xxx
            password: xxx

推荐方式

第三种方案,使用sqlSessionFactory实现批量插入(推荐)

@ResourceprivateSqlSessionFactory sqlSessionFactory;// 关闭session的自动提交SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH,false);try{UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    list.stream().forEach(user -> userMapper.saveInfo(user));// 提交数据
    sqlSession.commit();}catch(Exception e){
    sqlSession.rollback();}finally{
    sqlSession.close();}

优势:这种方式可以说是集第一种和第二种方式的优点于一身,既可以提高运行效率,又可以保证大数据量时执行成功,大数据量时推荐使用这种方式。

其他方式

批量修改方案

第一种 for

<!-- 批量更新第一种方法,通过接收传进来的参数list进行循环着组装sql --><updateid="updateBatch"parameterType="java.util.List"><foreachcollection="list"item="item"index="index"open=""close=""separator=";">
            update people
            <set><iftest="item.firstName != null">
                    first_name = #{item.firstName,jdbcType=VARCHAR},
                </if><iftest="item.lastName != null">
                    last_name = #{item.lastName,jdbcType=VARCHAR},
                </if></set>
            where id = #{item.id,jdbcType=BIGINT}
        </foreach></update>

第二种 case when

<!-- 批量更新第二种方法,通过 case when语句变相的进行批量更新 --><updateid="updateBatch2"parameterType="java.util.List">
        update people
        <trimprefix="set"suffixOverrides=","><trimprefix="first_name = case"suffix="end,"><foreachcollection="list"item="i"index="index"><iftest="i.firstName!=null">
                        when id=#{i.id} then #{i.firstName}
                    </if></foreach></trim><trimprefix="last_name = case"suffix="end,"><foreachcollection="list"item="i"index="index"><iftest="i.lastName!=null">
                        when id=#{i.id} then #{i.lastName}
                    </if></foreach></trim></trim>
        where id in
        <foreachcollection="list"index="index"item="item"separator=","open="("close=")">
            #{item.id,jdbcType=BIGINT}
        </foreach></update>

第三种 replace into

<!-- 批量更新第三种方法,通过 replace into  --><updateid="updateBatch3"parameterType="java.util.List">
    replace into people
    (id,first_name,last_name) values
    <foreachcollection="list"index="index"item="item"separator=",">
        (#{item.id},
        #{item.firstName},
        #{item.lastName})
    </foreach></update>

第四种 ON DUPLICATE KEY UPDATE

<!-- 批量更新第四种方法,通过 duplicate key update  --><updateid="updateBatch4"parameterType="java.util.List">
        insert into people
        (id,first_name,last_name) values
        <foreachcollection="list"index="index"item="item"separator=",">
            (#{item.id},
            #{item.firstName},
            #{item.lastName})
        </foreach>
        ON DUPLICATE KEY UPDATE
        id=values(id),first_name=values(first_name),last_name=values(last_name)
    </update>

效率比较

image

总结

sql语句for循环效率其实相当高的,因为它仅仅有一个循环体,只不过最后update语句比较多,量大了就有可能造成sql阻塞。

case when虽然最后只会有一条更新语句,但是xml中的循环体有点多,每一个case when 都要循环一遍list集合,所以大批量拼sql的时候会比较慢,所以效率问题严重。使用的时候建议分批插入。

duplicate key update可以看出来是最快的,但是一般大公司都禁用,公司一般都禁止使用replace into和INSERT INTO … ON DUPLICATE KEY UPDATE,这种sql有可能会造成数据丢失和主从上表的自增id值不一致。而且用这个更新时,记得一定要加上id,而且values()括号里面放的是数据库字段,不是java对象的属性字段

标签: mybatis java 大数据

本文转载自: https://blog.csdn.net/qq_32389095/article/details/140711223
版权归原作者 极北之南。 所有, 如有侵权,请联系我们删除。

“mybatis批量更新”的评论:

还没有评论