MyBatis动态SQL中数值0更新失效问题解析与解决方案

 更新时间:2026年06月26日 09:03:04   作者:尽兴-  
本文详细解析了MyBatis动态SQL中数值字段更新失效的问题,指出使用FastJSON的JSONObject接收入参时应避免混用字符串、数字判断,并提出两种解决方案,推荐采用数值字段最优方案,需要的朋友可以参考下

一、问题现象

业务场景为物料库存更新接口,使用 FastJSON 的 JSONObject 接收入参,MyBatis 动态 SQL 通过 <if> 标签判断字段是否参与更新:

  1. 入参 newQuantity 传入数值 0(Integer 类型);
  2. XML 中判断条件:<if test="newQuantity != null and newQuantity != ''">
  3. 最终打印的执行 SQL 完全没有拼接 invt = #{newQuantity} 这一段,库存字段未更新;
  4. newQuantity 传入大于 0 的数字(如 2、5)时,SQL 正常拼接,更新逻辑生效。

二、根因分析

1. OGNL 表达式底层判定规则

MyBatis 的 <if test> 使用 OGNL 表达式做条件判断,当数字 0 与**空字符串 ''**做不等对比时:
0 != '' 的运算结果为 false
完整条件 newQuantity != null and newQuantity != '' 逻辑拆解:

  • newQuantity=0,newQuantity != null → true;
  • newQuantity != '' → false;
  • true && false 整体条件不成立,<if> 分支直接跳过,对应字段不会拼入 SQL。

2. 混用字符串、数字判断是核心误区

!= '' 是专门用于字符串类型的判空逻辑,用来过滤前端传过来的空字符串 ""
而库存、金额、单价、税额这类字段,存储类型为 Integer/BigDecimal,入参只会是 null 或数字,永远不会出现空字符串,强行叠加 != '' 判断会拦截数值 0。

3. 同类受影响字段

代码中所有金额、数值字段都存在相同隐患:
amount_inclusive_taxunit_pramount_taxamount_no_tax,当传入 0 时都会出现更新失效。

三、两种解决方案

方案 1:数值字段最优方案(推荐)

数字类型字段仅判断 null,直接删除 != '' 条件,不做空字符串校验:

<!-- 库存数量(Integer) -->
<if test="newQuantity != null">
    invt = #{newQuantity},
</if>
<!-- 含税金额(BigDecimal) -->
<if test="amount_inclusive_tax != null">
    amount_inclusive_tax = #{amount_inclusive_tax},
</if>

优势:逻辑简洁、无多余运算,完美兼容 0、正数、负数等所有数字场景。

方案 2:兼容字符串 + 数字混合入参场景

若字段存在同时接收字符串、数字的特殊场景,补充数字 0 的判断逻辑:

<if test="newQuantity != null and (newQuantity != '' or newQuantity == 0)">
    invt = #{newQuantity},
</if>

劣势:多一层逻辑判断,纯数值业务不推荐使用。

四、规范区分:什么时候用!= '',什么时候只用!= null

  1. 字符串字段(名称、编码、备注、地址)
    需要双重判断,过滤 null 和前端空字符串:
<if test="artiName != null and artiName != ''">
    arti_name = #{artiName},
</if>
  1. 数值字段(Integer、Long、BigDecimal、Double)
    仅判断非 null,禁止加 != ''
<if test="changeQuantity != null">
    invt = #{changeQuantity},
</if>

五、修正后完整 XML 示例

<update id="updateInvtQuantity" parameterType="com.alibaba.fastjson.JSONObject">
    UPDATE LCP_ARTI_MATN_HQZX
    SET
    <if test="newQuantity != null">
        invt = #{newQuantity},
    </if>
    <if test="amount_inclusive_tax != null">
        amount_inclusive_tax = #{amount_inclusive_tax},
    </if>
    <if test="unit_pr != null">
        unit_pr = #{unit_pr},
    </if>
    <if test="amount_tax != null">
        amount_tax = #{amount_tax},
    </if>
    <if test="amount_no_tax != null">
        amount_no_tax = #{amount_no_tax},
    </if>
    sysupdatedate = SYSDATE,
    sysupdateoruuid = #{syscreatoruuid},
    sysupdateoruuidname = #{syscreatoruuidname}
    WHERE matn_id = #{matnId}
    AND sysisdelete = '0'
</update>

六、总结避坑要点

  1. 数字字段不要混用空字符串判断 != '',会拦截数值 0;
  2. 严格区分字段类型,字符串双重判空、数值仅判 null;
  3. 开发完成后务必覆盖入参为 0 的场景做单元测试,避免库存清零、金额置零等业务逻辑失效;
  4. 打印 MyBatis 执行 SQL 日志辅助排查动态分支是否正常拼接。

以上就是MyBatis动态SQL中数值0更新失效问题解析与解决方法的详细内容,更多关于MyBatis动态SQL数值0更新失效的资料请关注脚本之家其它相关文章!

相关文章

  • Spring Cloud Alibaba之Sentinel实现熔断限流功能

    Spring Cloud Alibaba之Sentinel实现熔断限流功能

    这篇文章主要介绍了Spring Cloud Alibaba之Sentinel,这里使用阿里的sentinel来实现熔断限流功能,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • java检测redis是否可用的方法示例

    java检测redis是否可用的方法示例

    这篇文章主要给大家介绍了关于java检测redis是否可用的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-08-08
  • Mybatis-Plus 官方神器发布

    Mybatis-Plus 官方神器发布

    mybatis-mate 为 mp 企业级模块,支持分库分表,数据审计、数据敏感词过滤(AC算法),字段加密,字典回写(数据绑定),数据权限,表结构自动生成 SQL 维护等,旨在更敏捷优雅处理数据,今天介绍一个 MyBatis - Plus 官方发布的神器,感兴趣的朋友一起看看吧
    2021-11-11
  • springboot在idea下debug调试热部署问题

    springboot在idea下debug调试热部署问题

    这篇文章主要介绍了springboot在idea下debug调试热部署问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • IDEA 2020.1 版自动导入MAVEN依赖的方法(新版MAVEN无法自动导入/更新POM依赖、MAVEN设置自动更新、自动更新快捷键)

    IDEA 2020.1 版自动导入MAVEN依赖的方法(新版MAVEN无法自动导入/更新POM依赖、MAVEN设置自动更

    这篇文章主要介绍了IDEA 2020.1 版自动导入MAVEN依赖的方法(新版MAVEN无法自动导入/更新POM依赖、MAVEN设置自动更新、自动更新快捷键),需要的朋友可以参考下
    2020-08-08
  • Java 记录类Record详解

    Java 记录类Record详解

    文章介绍了Java记录类的引入背景、语法特点及优势,包括自动生成构造器、访问器、equals、hashCode、toString等方法,强调其不可变性与类型安全性,适合用于数据封装,并通过示例和注意事项说明其使用场景与局限,感兴趣的朋友跟随小编一起看看吧
    2025-09-09
  • java解析Excel/导入信息到Excel方式

    java解析Excel/导入信息到Excel方式

    这篇文章主要介绍了java解析Excel/导入信息到Excel方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • SpringCloud整合MQ实现消息总线服务方式

    SpringCloud整合MQ实现消息总线服务方式

    这篇文章主要介绍了SpringCloud整合MQ实现消息总线服务方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-05-05
  • spring boot udp或者tcp接收数据的实例详解

    spring boot udp或者tcp接收数据的实例详解

    这篇文章主要介绍了spring boot udp或者tcp接收数据,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • 使用Java把文本内容转换成网页的实现方法分享

    使用Java把文本内容转换成网页的实现方法分享

    这篇文章主要介绍了使用Java把文本内容转换成网页的实现方法分享,利用到了Java中的文件io包,需要的朋友可以参考下
    2015-11-11

最新评论