项目场景:
最近公司有个数据库敏感字段加密改造的项目,需要将敏感字段加上统一后缀(_enc),使用的是shardingshere数据加密的功能来将代码的字段,映射到数据库字段。通过修改数据库表和应用的shardingshere的数据规则映射配置就行。但是自测的过程中,历史代码在update 某条数据记录的时候,直接更新了整个库,特此记录一下这个问题。
问题描述
业务有个根据手机号更新A表记录的接口,但是自测的时候,直接更新了整个表,shardingshere的logicSQL和Actual SQL如下所示:
数据更新的语义直接被改变。
原因分析:
看了一下Mapper文件,是之前同事mybatis动态sql使用的问题,在update的时候直接使用了if标签,造成了这个问题。Mapper的示意代码如下:
<update id="updateXXX">
update XXX set
<if test="sendTime!= null">send_time=#{sendTime},</if>
<if test="updateTime!= null">update_time=#{updateTime},</if>
<if test="updateId!= null">update_id=#{updateId}</if>
where mobile=#{mobile}
</update>
解决方案:
(1)使用set标签标签即可解决
<update id="updateXXX">
update XXX
<set>
<if test="sendTime!= null">send_time=#{sendTime},</if>
<if test="updateTime!= null">update_time=#{updateTime},</if>
<if test="updateId!= null">update_id=#{updateId}</if>
</set>
where mobile=#{mobile}
</update>
(2)使用trim标签
<update id="updateXXX">
update XXX
<trim prefix="SET" suffixOverrides=",">
<if test="sendTime!= null">send_time=#{sendTime},</if>
<if test="updateTime!= null">update_time=#{updateTime},</if>
<if test="updateId!= null">update_id=#{updateId}</if>
</trim>
where mobile=#{mobile}
</update>
总结:
涉及到条件判断的情况,尽量使用trim、where、set标签,做好防御编程。详细的可以查看mybaitis官网的动态SQL