MyBatis if判断解析Integer为0的属性不成立;MyBatis动态SQL表达式的“坑”;=与==;

本文探讨了在MyBatis中正确使用判空语句的方法,解决了Integer类型为0时被视为null的问题,并提供了针对不同数据类型的正确判空策略。

说在前面:

      遇到问题时在网上看到两篇文章,虽然都能解决问题,但是第一篇的原因解释有问题,第二篇解释对了,但是太累赘,所以整合了一下。已放入原作者地址,若觉得不详细可以去原作者那里继续研究。

参考地址:https://www.cnblogs.com/chenhao-/p/7206482.html

场景描述:

       使用Mybatis时,常常会判断属性是否为空,当type为Integer类型,并且type值为0时,该if判断却为false。

<if test="type != null and type != ''">  
    and type = #{type}   
</if>  

解决办法:

      删除and及后面的判断

<if test="type != null">  
    and type = #{type}   
</if>  

原因:

      参考地址:https://www.jianshu.com/p/91ed365c0fdd

       Mybatis的源码中表达式是用OGNL解析的,OGNL对于boolean的定义和JavaScript有点像,即:0==''这是一个true的条件,大家可以在浏览器的控制台尝试,如下图。可以不难理解<if test="type != null and type != ''">  ,当type=0时会出现的问题了。问题的根源来自编码的不规范,只有String类型才需要判断是否!='',其他类型完全没有必要判断!=''。    

        这里有必要再提一个“坑”,如果你有类似于String str ="A"; <if test="str!= null and str == 'A'">这样的写法时,你要小心了。因为单引号内如果为单个字符时,OGNL将会识别为Java 中的 char类型,显然String 类型与char类型做==运算会返回false,从而导致表达式不成立。解决方法很简单,修改为<if test='str!= null and str == "A"'>即可。

-----------------------------------后期补充-----------------------------------

Mybatis异常:
java.lang.IllegalArgumentException: invalid comparison:java.util.Date and java.lang.String

原因:在Mapper.xml中对非字符串类型的数据进行了是否为空判断,如date、decimal类型的数据进行 != ''就会报如上错误,只有字符串才需要非空判断

参考地址:https://www.cnblogs.com/coffee9527/p/9179941.html

-----------------------------------后期补充-----------------------------------

=与==关于引号的使用

=情况

<if test="isMapping!=null and isMapping != '1'">

==时,单引号双引号对换

<if test='isMapping!=null and isMapping == "1"'>

参考地址:https://www.cnblogs.com/sxdcgaq8080/p/9443023.html

<think>好的,用户现在的问题是关于MyBatis中如何判断SQL参数是否为空的解决方案。我需要结合他们提供的引用内容来给出准确的回答。 首先,用户提到了参考引用[1],里面详细介绍了MyBatis动态SQL标签,比如trim、where、set、foreach、if等。特别是if标签用于条件判断,这正是用户需要的。所以,我应该重点讲解如何使用<if>标签来判断参数是否非空。 接下来,用户提供的引用[1]中有一个例子,使用<if test="column1!='' and column1!=null">,这说明在MyBatis中可以通过同时检查空字符串和null来判断参数是否存在。需要提醒用户注意这两个条件的顺序,避免可能的错误。例如,如果参数是null的话,先检查是否等于空字符串可能会导致异常,所以正确的顺序应该是先判断null,再判断空字符串。 另外,用户还提到了引用[3]中关于Integer比较的注意事项。虽然这和动态SQL没有直接关系,但可能用户在使用条件判断时,如果参数是包装类型,需要注意使用equals而==过这个问题可能超出了当前问题的范围,但可以作为补充提醒。 用户的需求可能是在编写动态SQL时,如何避免参数为空导致的问题,比如拼接必要的条件或者语句错误。因此,我应该给出几种常见的场景和对应的解决方案,比如在WHERE子句中使用<where>标签结合<if>,在UPDATE语句中使用<set>标签,以及如何处理多个条件的情况。 此外,用户可能需要知道如何优化这些条件判断,比如使用MyBatis-Plus的注解或者其他工具,如引用[2]提到的MybatisX插件,这可以提升开发效率,但用户的问题主要集中在条件判断本身,所以这部分可以作为附加建议。 最后,确保回答结构清晰,分点说明,并且给出示例代码,这样用户能够更直观地理解如何应用这些解决方案。同时,根据用户要求生成相关问题,帮助用户进一步深入理解。</think>### MyBatis判断SQL参数非空的解决方案 在MyBatis中实现动态SQL参数非空判断,主要通过以下方法实现: --- #### 1. **基础条件判断:`<if>`标签** 通过`<if test="条件表达式">`实现条件筛选,避免空值参数拼接进SQL语句: ```xml <select id="selectByCondition" resultType="User"> SELECT * FROM user <where> <if test="username != null and username != ''"> <!-- 同时判空和空字符串 --> username = #{username} </if> <if test="age != null"> AND age = #{age} </if> </where> </select> ``` - **注意点**: - 字符串参数需同时判断`null`和空字符串(`''`)[^1] - 数值类型只需判断`null` --- #### 2. **复合条件处理:`<trim>`标签** 当动态条件较多时,用`<trim>`标签自动处理多余的关键字(如`AND`、`OR`)或符号(如逗号): ```xml <insert id="insertUser"> INSERT INTO user <trim prefix="(" suffix=")" suffixOverrides=","> <!-- 自动去除尾部逗号 --> <if test="username != null">username,</if> <if test="age != null">age,</if> </trim> VALUES <trim prefix="(" suffix=")" suffixOverrides=","> <if test="username != null">#{username},</if> <if test="age != null">#{age},</if> </trim> </insert> ``` --- #### 3. **UPDATE语句优化:`<set>`标签** 自动处理UPDATE语句中的逗号问题: ```xml <update id="updateUser"> UPDATE user <set> <if test="username != null">username = #{username},</if> <if test="age != null">age = #{age},</if> </set> WHERE id = #{id} </update> ``` - **优势**:自动去除最后一个多余的逗号[^1] --- #### 4. **集合遍历:`<foreach>`标签** 处理集合参数时,可遍历非空集合: ```xml <select id="selectByIds" resultType="User"> SELECT * FROM user WHERE id IN <foreach collection="ids" item="id" open="(" separator="," close=")"> #{id} </foreach> </select> ``` --- ### 常见问题优化 1. **参数类型差异** - 字符串:需判断`null`和`''` - 数值类型:只需判断`null` - 包装类(如`Integer`):推荐使用`equals`判断值,而非`==`(避免缓存范围外的对象比较问题)[^3] 2. **工具推荐** - 安装`MyBatisX`插件:可自动生成动态SQL代码片段,减少手写错误[^2] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值