Mybatis+0+null,小问题引发的血案

简介: 版权声明:欢迎转载,请注明沉默王二原创。 https://blog.csdn.net/qing_gee/article/details/50518795 Mybatis在进行判空操作...
版权声明:欢迎转载,请注明沉默王二原创。 https://blog.csdn.net/qing_gee/article/details/50518795

Mybatis在进行<if test="status != null and status != ''">判空操作时,如果status为0的时候,该判断条件的值为false,也就是说Mybatis此时把0作为null来进行判断的,所以遇到这种情况时,只能按照下面这个方法来办!

一、源码调查结果

遇到这个问题时,我翻看了Mybatis的源码,发现其在ExpressionEvaluator.java类的evaluateBoolean方法处返回了false,这个源码包的分析方式和源码分析 There is no getter for property named ‘*’ in ‘class java.lang.String有极大的相同之处。

但发现了问题,也然并卵,修改Mybatis的源码我是不行,所以只能曲线救国!

二、场景分析

数据库字段

  `status` tinyint(2) NOT NULL COMMENT '0未支付,1已支付',

此时0表示未支付,1表示支付,那么按照一般的逻辑来看,查询语句需要写成这样的形式:

select * from ym_deals y WHERE d.deal_id = 1

        <if test="status != null and status != ''">
    and y.status = #{status}
</if>

其意义在于,当查询参数不传递未支付或者支付条件时,就需要查询status为0和1的全部结果,也就是说没有条件and y.status = #{status},但事实就纠结了,当status传递的参数为1时,if条件的结果为true,也就是说sql语句变成了select * from ym_deals y WHERE d.deal_id = 1 and y.status=1,查询结果正常,但如果status为0此时,sql语句变成了select * from ym_deals y WHERE d.deal_id = 1,与预期结果select * from ym_deals y WHERE d.deal_id = 1 and y.status=0显然是不符的!

也就是说,Mybatis自作主张的把status为0的条件当做了if的false结果!

三、解决办法

①、对传递参数拦截

    public static int parseStringToInt(Object parameter, int defualtValue) {
        try {
            if ((parameter == null) || (parameter.equals(""))) {
                return defualtValue;
            }
            return Integer.parseInt(parameter.toString());
        } catch (Exception ex) {
        }
        return 0;
    }
vo.addParams("status", StrUtil.parseStringToInt(vo.getParams("status"), -1));

也就是说在查询所有支付状态的订单时,把status的值转换为-1.

②、重构Mybatis的查询语句

select * from ym_deals y WHERE d.deal_id = 1

        <if test="status != -1">
    and y.status = #{status}
</if>

此时不再判空,而判-1。

按照以上的办法就解决了问题,不知道你那是否有更好的解决办法?


四、后记

这篇文章发表之后,有热心的朋友给出下面的解决办法:

lengjian68 status是Integer 类型的 把status!=‘’ 给去掉
去掉就好了

1楼 qq_30159115 确定是 int类型的就不用 判断 status != ‘’ 就搞定了

Re: Optimistic_ 发表 回复qq_30159115:给力啊!感谢!
判断不是为空,对于int类型就是在判断不为0么?

按照朋友给出的观点,我尝试了一下,结果如朋友所说,status确定为integer类型的,把status!=”给去掉就好了。

那么现在重新来看,我本来的做法就有问题,integer类型的,我干嘛要用status!=”来进行判断,这显然是一种不负责任的做法,至于<if test="status != null and status != ''">的判断条件,显然是错误的,从原则上来讲,该判断条件只能来判断status为string类型的,用来判断integer类型,岂不贻笑大方,至于后面我提出的解决方案,显然也就无力苍白,我只想把这篇文章立马删掉,好不再误导他人。

但看到

Re: Optimistic_ 发表 回复qq_30159115:给力啊!感谢!
判断不是为空,对于int类型就是在判断不为0么?

下面这位朋友的疑问,我觉得,这篇文章存在还有一些价值,因为还有和我一样的朋友在犯错,“判断不是为空,对于int类型就是在判断不为0么?”这种认识显然是另外一种错误,integer类型很明显存在为null的情况,那么对于int类型当然不是在判断为0的。(当然了,这位仁兄说int类型,在严格意义上讲,就不存在null的可能了,那么我只能武断的推测任务,这位朋友是在说integer,请原谅我的鲁莽)

那么得出以下结论:

  1. <if test="status != null">中status为integer类型的,status=0的判断结果为true。
  2. <if test="status != null and status != ''">中status为integer类型的,status=0的判断结果为false,mybatis把status作为了string来进行判断。
  3. 如果status为integer,提前对status进行去空操作,再判断<if test="status != -1">在有的时候也是一种曲线救国。

相关文章


感谢您阅读【沉默王二的博客】,如果王二的博客给您带来一丝帮助或感动,我(也就是王二)将不甚荣幸。
如果您碰巧喜欢,可以留言或者私信我,这将是我鼓捣更多优秀文章的最强动力。

相关文章
|
5月前
|
SQL Java 数据库连接
MyBatis【源码探究 01】mapper.xml文件内<if test>标签判断参数值不等于null和空(当参数值为0)时筛选条件失效原因分析
MyBatis【源码探究 01】mapper.xml文件内<if test>标签判断参数值不等于null和空(当参数值为0)时筛选条件失效原因分析
543 0
MyBatis【源码探究 01】mapper.xml文件内<if test>标签判断参数值不等于null和空(当参数值为0)时筛选条件失效原因分析
|
3月前
|
Java 数据库连接 数据库
mybatis plus 更新值为null的字段
mybatis plus 更新值为null的字段
48 7
|
4月前
|
SQL Java 数据库连接
MyBatis-Plus更新使用null值
MyBatis-Plus更新使用null值
190 2
|
5月前
|
XML Java 数据库连接
MyBatis返回Map时值为null的字段会丢失
MyBatis返回Map时值为null的字段会丢失
108 2
|
12月前
|
SQL Java 数据库
【Mybatis-plus异常】mybatis-plus updateById方法更新不了空字符串和null的解决方法
【Mybatis-plus异常】mybatis-plus updateById方法更新不了空字符串和null的解决方法
478 0
|
5月前
|
Java 数据库连接 mybatis
mybatis plus字段为null或空字符串把原来的数据也更新了,只需要注解
mybatis plus字段为null或空字符串把原来的数据也更新了,只需要注解
160 0
|
5月前
|
SQL Java 数据库连接
Mybatis 查询出来的数据集合数量正确,但是具体数据为null
Mybatis 查询出来的数据集合数量正确,但是具体数据为null
157 1
|
12月前
|
XML Java 数据库连接
MyBatis参数映射问题解决教程: org.apache.ibatis.type.TypeException: Error setting non null for parameter #1 wit
MyBatis参数映射问题解决教程: org.apache.ibatis.type.TypeException: Error setting non null for parameter #1 wit
838 1
|
SQL 存储 XML
Mybatis返回集合类型到底是空集合还是null?源码解读
Mybatis返回集合类型到底是空集合还是null?源码解读
235 0