Spring mvc 如果特定列的参数为空,Mybatis将跳过更新该列

Spring mvc 如果特定列的参数为空,Mybatis将跳过更新该列,spring-mvc,mybatis,Spring Mvc,Mybatis,我在映射器中有以下更新查询 <update id="updTest" parameterType="TestDTO"> <![CDATA[ UPDATE TEST_USER SET EMAIL = #{email, jdbcType=VARCHAR} , USERNAME = #{username, jdbcType=VARCHAR}

我在映射器中有以下更新查询

<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,则跳过更新列。

我有一张表格,用户将在下面填写

  • 职务
  • 大小
  • 流动的
  • 出生
  • 地位
这是在成功登录后提供的附加信息。但当用户填写并提交表单时,更新过程非常有效


但是现有的
电子邮件、用户名、密码
和其他设置为
null
,除了表单中的6个字段。
这让我抓狂,我一直认为Mybatis会跳过更新字段,如果它的参数是
null
。它有什么特殊的配置吗?

你的抱怨是SQL,而不是MyBatis。如果update语句包含saySET mobile=null,SQL就会这样做

但MyBatis使用if语句提供了良好的动态SQL工具。看见这将使您在定制解决方案方面走上正轨

也可以考虑改变你的模式(如果它在你的控制之下)。应该有一个数字用户ID字段作为主键,由序列或类似项分配。或者,在这种情况下,用户名是公共密钥。这两种方法都将简化您的WHERE子句,并且几乎是标准做法。目前,电子邮件似乎是主键的一部分,因此更改电子邮件地址将意味着他们成为不同的用户

最后一句话。我从未在MyBatis SQL查询中使用过CDATA,但它可能没有什么坏处

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

  • 你的WHERE子句真奇怪。如果一个六口之家共享相同的电子邮件地址,您真的想在其中一个登录时更新所有六条记录吗?您需要决定一个唯一的主键,用户名是非常有意义的
  • 决定将USERNAME作为表的唯一主键后,可以删除WHERE子句的最后两行,还可以将USERNAME从集合列表中删除,因为它永远不会更改
  • 你将如何处理现有用户决定不再拥有手机的情况?在这种情况下,似乎确实需要将MOBILE设置为null
  • AUTH_标记字段在数据库中很奇怪。授权令牌通常只在登录会话期间有效-但我可能误解了您的用例
回到您的评论,我建议您编写一个MyBatis更新,只更新表单上的六个字段(命名为类似updateLoginFields的内容),并使用WHERE子句只指定用户名。您不需要担心空值,因为您可以控制呈现层中的可选内容


这是唯一的方法吗?我不想在所有查询中都使用
column=param
,除非这是存档此项的唯一选项。请参阅上面的扩展答案。
字段是关键列,因此我不需要在查询中使用
条件。这只是一个例子,不是一个实用的代码。不管怎样,我意识到动态查询是唯一的方法来实现它。谢谢你的建议和所有细节。我投票赞成你的。