如果其参数为null,则跳过Mybatis更新特定列

时间:2015-06-16 06:04:49

标签: spring-mvc mybatis

我在MAPPER中有一个更新的查询

<update id="updTest" parameterType="TestDTO">
    <![CDATA[
        UPDATE   TEST_USER

        SET      
              EMAIL          =  #{email, jdbcType=VARCHAR}
            , USERNAME       =  #{username, jdbcType=VARCHAR}
            , PASSWORD       =  #{password, jdbcType=VARCHAR}
            , DOMAIN         =  #{domain, jdbcType=VARCHAR}
            , COMPANY        =  #{company, jdbcType=VARCHAR}
            , DEPARTMENT     =  #{department, jdbcType=VARCHAR}
            , JOBTITLE       =  #{jobtitle, jdbcType=VARCHAR}
            , SIZE           =  #{size, jdbcType=INTEGER}
            , SEX            =  #{sex, jdbcType=VARCHAR}
            , BIRTH          =  #{birth, jdbcType=VARCHAR}
            , MOBILE         =  #{mobile, jdbcType=VARCHAR}
            , STATUS         =  #{status, jdbcType=VARCHAR}
            , AUTH_KEY       =  #{authKey, jdbcType=VARCHAR}
            , UPDATE_DATE    =  SYSDATE
            , UPDATE_ID      =  #{updateId, jdbcType=VARCHAR}
            , CREATE_DATE    =  SYSDATE
            , CREATE_ID      =  #{createId, jdbcType=VARCHAR}
            , DEL_YN         =  #{delYn, jdbcType=VARCHAR}
            , DEL_ID         =  #{delId, jdbcType=VARCHAR}

        WHERE   USERNAME= #{username, jdbcType=VARCHAR} 
        OR      EMAIL = #{email, jdbcType=VARCHAR}
        OR      AUTH_KEY = #{authKey, jdbcType=VARCHAR}
    ]]>
</update>

我想要实现的目标 如果列参数为null,则跳过更新列。

我有一个表单,用户将在下面填写这些表单。

  • JOBTITLE
  • 尺寸
  • MOBILE
  • SEX
  • STATUS

这是成功登录后的其他信息。但是当用户填写表单并提交表单时,更新过程效果很好。

但现有的EMAIL, USERNAME, PASSWORD和其他设置为null,除了表单中的那6个字段。它让我发疯,我一直认为Mybatis会跳过更新该字段的参数为null。它有什么特殊的配置吗?

1 个答案:

答案 0 :(得分:1)

你的抱怨是SQL,而不是MyBatis。如果您的更新语句包含说 SET mobile = null ,则SQL将执行此操作。

但MyBatis使用 if 语句提供了良好的动态SQL工具。见https://mybatis.github.io/mybatis-3/dynamic-sql.html。这应该会让您走上正确的解决方案。

另外,请考虑更改架构(如果它在您的控制之下)。应该有一个数字userId字段作为主键,由序列或类似物分配。或者,USERNAME是此类情况下的常用密钥。要么简化 WHERE 子句,要么是标准做法。目前,EMAIL似乎是主键的一部分,因此更改电子邮件地址将意味着他们成为不同的用户。

最后的评论。我从来没有在MyBatis SQL查询中使用 CDATA ,但它可能没什么坏处。

&LT; editFollowingComment&GT;

我认为您需要重新审视自己的要求,因为有些内容并没有多大意义。

  • 你的WHERE子句真的很奇怪。如果一个六口之家都拥有相同的电子邮件地址,您真的想在登录时更新所有六条记录吗?您需要决定一个唯一的主键,USERNAME非常有意义。
  • 决定将USERNAME作为表的唯一主键,您可以删除WHERE子句的最后两行,并将USERNAME从SET列表中删除,因为它永远不会更改。
  • 您如何处理现有用户的情况,决定他们不再拥有移动设备?在这种情况下,您似乎需要将MOBILE设置为null。
  • AUTH_TOKEN字段是一个在数据库中查找的奇怪字段。授权令牌通常仅在登录会话期间有效 - 但我可能误解了您的用例。

回到你的评论,我建议你编写一个MyBatis更新,它只更新表单上的六个字段(名称类似于updateLoginFields),并带有一个仅指定USERNAME的WHERE子句。您无需担心空值,因为您可以控制presentaion图层中的可选内容。

&LT; / editFollowingComment&GT;