如果其参数为空,Mybatis 将跳过更新特定列

Mybatis skipping update the specific column if its parameter is null

我在 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>

我想要实现的目标 是跳过参数为空的列的更新。

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

这是附加信息,在成功登录后出现。但是当用户填写表单并提交时,更新过程非常有效。

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

你抱怨的是 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,但它可能没有害处。

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

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

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