Mybatis-0值问题

前言

在使用Mybatis的时候,曾遇到过一个奇怪的问题,当使用<if test="status != null and status != ''">判空操作时,如果status为0的时候,该判断条件的值为false,也就是说Mybatis此时把0作为null来进行判断的。

遇到这个问题的时候,翻看Mybatis的源码,发现其在ExpressionEvaluator.java类的evaluateBoolean方法处返回了false。

ExpressionEvaluator.java-evaluateBoolean

场景分析

数据库字段

1
`pay_status` int(11) NOT NULL DEFAULT '0' COMMENT '支付状态 0-未支付 1-已支付',

按照一般的逻辑来看,查询语句需要写成这样的形式:

1
2
3
4
select * from order_pay pay WHERE pay.deal_id = 1
<if test="payStatus != null and payStatus != ''">
and pay.pay_status = #{payStatus}
</if>

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

Mybatis自作主张的把payStatus为0的条件当做了if的false结果!

解决办法

方法一

payStatus是Integer类型的,把payStatus != '' 去掉就可以了。

那么现在重新来看,先前的做法本来就有问题,integer类型的,干嘛要用payStatus!=''来进行判断,这显然是不对的,从原则上来讲,<if test="payStatus != null and payStatus != ''">该判断条件只能来判断payStatus为string类型的,不能用来判断integer类型。

但由此引发一个疑问:<if test="payStatus != null and payStatus != ''">判断不是为空,对于Integer类型就是在判断不为0么?

方法二

对传递参数拦截

1
2
3
4
5
6
7
8
9
10
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;
}
1
vo.addParams("status", StrUtil.parseStringToInt(vo.getParams("status"), -1));

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

重构Mybatis的查询语句

1
2
3
4
select * from order_pay pay WHERE pay.deal_id = 1
<if test="payStatus != -1">
and pay.pay_status = #{payStatus}
</if>

本文标题:Mybatis-0值问题

文章作者:王洪博

发布时间:2019年08月01日 - 15:08

最后更新:2019年10月09日 - 10:10

原始链接:http://whb1990.github.io/posts/9dd16667.html

▄︻┻═┳一如果你喜欢这篇文章,请点击下方"打赏"按钮请我喝杯 ☕
0%