MyBatis中if标签正确使用方法(Integer类型)

场景

持久层:MyBatis
组合查询一组数据,字段有:String id,String name ,Integer status。
由于三个字段都可能为空,所以mapper文件中这样写的:

SELECT
        re.id,
        re.name,
        re.status
        FROM
        tj_registration_type re
        WHERE
        1=1
        <if test="id!='' and id!= null and id!='undefined'">
            AND re.id= #{id}
        </if>
        <if test="status!='' and status!= null and status!='undefined'">
            AND re.status= #{status}
        </if>
        <if test="name!='' and name!= null and name!='undefined'">
            AND re.name= #{name}
        </if>
        AND
        re.is_delete=0

status取值为0或1,当status字段传值时,程序就会报错,是数据类型出现了问题,但是status是Integer类型的,却提示“For input string:“undefined””。
在这里插入图片描述

尝试一

当将if标签中“and status!=‘undefined’”,status传值1,程序不再报错。SQL语句可以执行。但还是存在问题,继续尝试二。

尝试二

当if标签为:

     <if test="status!='' and status!= null ">

当status传值为0时SQL如下:

 SELECT
        re.id,
        re.name,
        re.status
        FROM
        tj_registration_type re
        WHERE
        1=1
    
        AND
        re.is_delete=0;

有没有发现一个问题? 没有 and status = 0 这一句话。

尝试三

将if标签改为如下,程序正确运行。

     <if test=" status!= null ">

最终mapper改为:

 SELECT
        re.id,
        re.name,
        re.status
        FROM
        tj_registration_type re
        WHERE
        1=1
        <if test="id!='' and id!= null ">
            AND re.id= #{id}
        </if>
        <if test="status!= null">
            AND re.status= #{status}
        </if>
        <if test="name!='' and name!= null ">
            AND re.name= #{name}
        </if>
        AND
        re.is_delete=0

原因

  • status=‘undefined’
    在这里应该是不需要判断undefined这种情况的,我在通过swagger测试的时候有种情况出现了undefined字段,所以加在了判断里,其实是错误的使用方式。
  • status=‘’
    MyBatis解析if标签时其表达式使用OGNL处理的。
    Interpreting Objects as Booleans
    Any object can be used where a boolean is required. OGNL interprets objects as booleans like this:
    If the object is a Boolean, its value is extracted and returned;
    If the object is a Number, its double-precision floating-point value is compared with zero; non-zero is treated as true, zero as false;
    If the object is a Character, its boolean value is true if and only if its char value is non-zero;
    Otherwise, its boolean value is true if and only if it is non-null.
    如果对象是Number类型,当传值为0时会被解析成false,否则为true,浮点型0.00也是如此。所以这里直接解析成false。只有String类型才需要判断是否!=’’,其他类型完全没有这个必要。
  • 拓展
    如果你有类似于String str =“A”; 这样的写法时,你要小心了。因为单引号内如果为单个字符时,OGNL将会识别为Java 中的 char类型,显然String 类型与char类型做==运算会返回false,从而导致表达式不成立。解决方法很简单,修改为即可

大佬博客:
https://jackyrong.iteye.com/blog/2377596
https://www.cnblogs.com/cxchanpin/p/7106568.html
http://commons.apache.org/proper/commons-ognl/language-guide.html

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值