mybatis批量更新遇到的坑

前言

实际上,我们经常会遇到这样的需求,那就是利用Mybatis批量更新或者批量插入(一般是sql语句有分号时有问题),但是,实际上即使Mybatis完美支持你的sql,你也得看看你操作的数据库是否支持。


问题

先带大家来看一段sql的配置,

<update id="updateState">
    <foreach collection="list" item="item" index="index"  separator=";">
      update wx_convert_detail
      <set>
        fahao=#{item.fahao},convert_time=#{item.convertTime},state=#{item.type},cause=#{item.reason}
      </set>
      WHERE id=#{item.id}
    </foreach>
  </update>

看似似乎没有一点问题,这里用到了Mybatis的动态sql,实际上说白了也就是拼sql,不过这个繁杂的工作交给Mybatis帮我们去做了。可是,只要一执行就要报语法错误。调试了好久,发现只要list的成员只有一个就没有问题。

解决方案

后来搜索发现,原来mysql的批量更新是要我们主动去设置的, 就是在数据库的连接url上设置一下,加上&allowMultiQueries=true 即可。当然这是因为我们更新多条记录多个字段为不同的值才需要修改,如果更改多条记录的同一字段是可以直接使用的。

jdbc.url= jdbc:log4jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true

扩展

上面这种批量更新相当耗效率,一条记录update一次,性能比较差,容易造成阻塞。

因为Mybatis映射文件中的sql语句不允许 ; 符号。按照可行的case when处理方式,也可以使用Mybatis映射文件书写方式如下:
<update id="updateState" parameterType="java.util.List">
    UPDATE wx_convert_detail SET
    fahao=
    <foreach collection="list" item="item" index="index" open="CASE id" close="END">
        WHEN #{item.id} THEN #{item.fahao}
    </foreach>
    ,convert_time=
    <foreach collection="list" item="item" index="index" open="CASE id" close="END">
        WHEN #{item.id} THEN #{item.convertTime}
    </foreach>
    ,state=
    <foreach collection="list" item="item" index="index" open="CASE id" close="END">
        WHEN #{item.id} THEN #{item.type}
    </foreach>
    ,cause=
    <foreach collection="list" item="item" index="index" open="CASE id" close="END">
        WHEN #{item.id} THEN #{item.reason}
    </foreach>
    WHERE id IN
    <foreach collection="list" item="item" index="index" separator="," open="(" close=")">
        #{item.id}
    </foreach>
</update>

同时,实际的业务系统里面oracle数据库也用的非常的多,当然,oracle数据库不需要做特殊的配置,但是相应的sql要做变化,加上begin和end。

<update id="updateState">
    <foreach collection="list" item="item" index="index" open="begin" close="end;" separator=";">
      update wx_convert_detail
      <set>
        fahao=#{item.fahao},convert_time=#{item.convertTime},state=#{item.type},cause=#{item.reason}
      </set>
      WHERE id=#{item.id}
    </foreach>
  </update>

总结

有些时候,遍寻代码而无错也找不到问题的时候,不妨去找找系统环境的问题,说不定,就只在一瞬,问题迎刃而解。

关于 allowMultiQueries=true的原理可以去关注下这篇博文https://my.oschina.net/zhuguowei/blog/411853

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值