引言
本次场景,公司通过shardingjdbc 对mysql数据库进行分表,模糊匹配 按照createTime,每季度一张表的方式,精确匹配按照creatTime的方式。关于模糊匹配、精确匹配,自行在shardingjdbc官网查看,分表策略等。
由于是跟进createTime字段去作为分表的key,那么在执行 select、update、delete操作时,需要携带creatTime 字段。
案例
在执行过程中,导入的操作,基于easyexcel 我采用分批次的方式,批量去进行update操作,于是我的sql如下:
<update id="batchUpdateTmsStatus">
<foreach collection="tmsFollowBOList" item="item" separator=";">
update bp_tms_logistics set expressStatus = #{item.expressStatus},userChange = 1,followStatus = #{item.status}
where createTime = #{item.createTime,jdbcType=DATE}
and expressNo = #{item.expressNo}
</foreach>
</update>
但是问题来了,通过日志发现,执行的sql脚本如下:
update xxxxx_2024_2
set expressStatus = ?,userChange = 1,followStatus = ?
where expressNo = ?
and createTime = ?;
update xxxxx
set expressStatus = ?,userChange = 1,followStatus = ?
where expressNo = ?
and createTime = BETWEEN
::: [3, 2, SF2223211, 2024-09-10, 2, 1, SF05050505, 2024-09-09]
细心的可以发现,一个是xxxxx_2024_2
一个是xxxxx
,其实 xxxxx对于我们来说它只是虚拟表,并不存在,我们需要的是xxxxx_2024_2
的形式,而shardingjdbc 并没有 通过代理的方式,代理到正确的数据库表中,查看官网issues 发现,并不支持批量update的方式,也就是我上面的语句。
issues:https://github.com/apache/shardingsphere/issues/6665
解决
由于并不支持批量的操作,刚开始的想法是想直接for循环链接数据库得了,但是我觉得这样并不符合自己的方式,于是,想了想,或许采用 case - when 的方式是否可以实现呢,于是我修改sql如下:
<update id="batchUpdateTmsStatus">
update xxxxx
<trim prefix="set" suffixOverrides=",">
<trim prefix="expressStatus=case" suffix="end,">
<foreach collection="tmsFollowBOList" item="item" index="index">
<if test="item.expressStatus != null">
when expressNo = #{item.expressNo} AND createTime = #{item.createTime,jdbcType=DATE} THEN #{item.expressStatus}
</if>
</foreach>
</trim>
<trim prefix="userChange=case" suffix="end,">
<foreach collection="tmsFollowBOList" item="item" index="index">
<if test="item.expressStatus != null">
when expressNo = #{item.expressNo} AND createTime = #{item.createTime,jdbcType=DATE} THEN 1
</if>
</foreach>
</trim>
<trim prefix="followStatus=case" suffix="end,">
<foreach collection="tmsFollowBOList" item="item" index="index">
<if test="item.status != null">
when expressNo = #{item.expressNo} AND createTime = #{item.createTime,jdbcType=DATE} THEN #{item.status}
</if>
</foreach>
</trim>
</trim>
</update>
里面的内容我就不解释了,采用这个方式可以解决批量update 的方式,其中 when 中的条件需要符合哈。
标签:expressStatus,update,xxxxx,item,分表,shardingJdbc,createTime,expressNo From: https://www.cnblogs.com/zgf123/p/18409594