mybatis动态SQL问题

项目场景:

最近公司有个数据库敏感字段加密改造的项目,需要将敏感字段加上统一后缀(_enc),使用的是shardingshere数据加密的功能来将代码的字段,映射到数据库字段。通过修改数据库表和应用的shardingshere的数据规则映射配置就行。但是自测的过程中,历史代码在update 某条数据记录的时候,直接更新了整个库,特此记录一下这个问题。

问题描述

业务有个根据手机号更新A表记录的接口,但是自测的时候,直接更新了整个表,shardingshere的logicSQL和Actual SQL如下所示:
mybatis动态SQL问题_第1张图片
数据更新的语义直接被改变。

原因分析:

看了一下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

你可能感兴趣的:(mybatis,java,mysql)