MyBatis批处理

  1. 减少了jdbc驱动与数据库服务器之间的网络传输开销
    使用batch前:执行一条sql就要进行一次网络IO开销,还要等待服务器响应结束后才能提交下一条sql。预编译n次,设置参数n次,执行n次
    使用batch之后:客户端的多条sql是一起提交给服务器的,一次batch只涉及到一次网络传输开销。预编译一次,设置参数n次,执行一次
    image

批处理注意项:

1. 使用批处理要注意分片大小,不易过大
2. 在使用mybatis内置批处理,本质上也就是jdbc的批处理时,jdbc连接参数要添加rewriteBatchedStatements=true批处理才会生效
3. jdbc相比于Mybatis批处理效率更高
4. 批处理本质上是将拼接好的sql及其填充的数据发送一次网络请求实现的,所以手动拼接sql也可以实现批处理插入
5. 使用sql拼接则不用开启rewriteBatchedStatements,需要设置allowMultiQueries=true,允许更新、修改时候多条sql可以用;分开一起提交到服务器中

手动拼sql

批量新增

<insert id="insertBatch">
    INSERT INTO `tb_user_info`(`login_account`, `password`, `username`, `dept_id`, `data_status`, `create_by`,
                               `create_time`,
                               `update_by`, `update_time`, `record_version`, `update_count`)
    VALUES
    <foreach collection="entities" item="entity" separator=",">
        (#{entity.loginAccount},
         #{entity.password},
         #{entity.username},
         #{entity.deptId},
         #{entity.dataStatus},
         #{entity.createBy},
         #{entity.createTime},
         #{entity.updateBy},
         #{entity.updateTime},
         #{entity.recordVersion},
         #{entity.updateCount})
    </foreach>
</insert>

批量修改

<update id="updateBatchById">
    <foreach collection="list" item="s" separator=";">
        update
            `t_student`
        set
            `name` = #{name},
            `age` = #{age}
        where
            id = #{id}
    </foreach>
</update>

注意:我们需要通过在数据库连接URL中指定allowMultiQueries参数值为true告诉数据库以支持";"号分隔的多条语句一块的执行,否则会报错

批量删除

使用foreach标签同批量修改、in操作都可以

MyBatis批处理

MyBatis批量新增本质上也是和上边一样手动拼接SQL,但要真正使用MyBatis批处理要指定jdbc驱动rewriteBatchedStatements为true,默认是false,默认false是因为连接属性rewriteBatchedStatements提供了一个非JDBC兼容的特性。并非所有语句都可以重写,并且可能会产生意想不到的结果。特别是关于处理错误和返回更新计数。

删除
batchDelete(10条记录)  =>  发送一次请求,内容为”delete from t where id = 1; delete from t where id = 2; delete from t where id = 3; ….”
或者
delete from t where id in(1,2,3,4,5,....n)

更新
batchUpdate(10条记录)  =>  发送一次请求,内容为”update t set … where id = 1; update t set … where id = 2; update t set … where id = 3 …”
新增
batchInsert(10条记录)  =>   发送一次请求,内容为”insert into t (…) values (…) , (…), (…)”

对delete和update,驱动所做的事就是把多条sql语句累积起来再一次性发出去;而对于insert,驱动则会把多条sql语句重写成一条sql语句,然后再发出去。

rewriteBatchedStatements与allowMultiQueries区别

1. rewriteBatchedStatements是重写sql语句达到发送一次sql的请求效果,
如上述MyBatis批处理,添加是insert into t (…) values (…) , (…), (…)使用逗号分隔,对于**insert**操作使用分号隔开sql语句,一次性发送

2. allowMultiQueries是针对于在xml的mapper中使用分号多个sql一块发送执行的,针对与**update,delete**,,默认不允许使用分号有多个sql语句一块执行的。

参考

Mybatis之批量更新数据(批量update) - 知乎 (zhihu.com)

调优 mybatis saveBatch 25倍性能

MySQL Jdbc驱动的rewriteBatchedStatements参数 关于批处理mysql中的rewritebatchedsta来个地瓜的博客-CSDN博客

posted @ 2024-05-12 19:06  永无八哥  阅读(163)  评论(0编辑  收藏  举报