博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mybatis 空字符串和0
阅读量:4563 次
发布时间:2019-06-08

本文共 3351 字,大约阅读时间需要 11 分钟。

最近在使用Mybatis的过程中遇到了一个奇怪的问题,如下所示:查询SQL中的一个状态条件,在param.sendstate=0或10时,单独处理. 

and (SendState = 2 and (RESPONSETYPETEXT is null or RESPONSETYPETEXT =''))
and (SendState = 0 or SendState = '' or SendState is null)
and SendState = #{param.sendstate}

但是,当param.sendstate为空字符串时,通过控制台打印的SQL发现执行的SQL是:

也就是说此时 param.sendstate == 0结果是true

这个问题困扰了我半天,最后改成如下形式解决

and (state = 10 and responsetext is null)
and (state = 0 or state is null)
and state = #{param.state}

由于时间紧急,没有深入去研究这个问题.后来看到了这篇文章

http://www.cnblogs.com/gushen-super/archive/2018/06/28/9238161.html

简单跟踪了下代码,明白了问题在哪.

Mybatis在处理 if 标签时,使用OGNL表达式处理并返回表达式的结果.

条件:param.sendstate == 0,此时param.sendstate是空字符串

OGNL在处理 == 运算时,最终调用的是 OgnlOps类的compareWithConversion方法

public static int compareWithConversion(Object v1, Object v2) {        int result;        if (v1 == v2) {            result = 0;        } else {            int t1 = getNumericType(v1);            int t2 = getNumericType(v2);            int type = getNumericType(t1, t2, true);            switch(type) {            case 6:                result = bigIntValue(v1).compareTo(bigIntValue(v2));                break;            case 9:                result = bigDecValue(v1).compareTo(bigDecValue(v2));                break;            case 10:                if (t1 == 10 && t2 == 10) {                    if (v1 instanceof Comparable && v1.getClass().isAssignableFrom(v2.getClass())) {                        result = ((Comparable)v1).compareTo(v2);                        break;                    }                    throw new IllegalArgumentException("invalid comparison: " + v1.getClass().getName() + " and " + v2.getClass().getName());                }            case 7:            case 8:                double dv1 = doubleValue(v1);                double dv2 = doubleValue(v2);                return dv1 == dv2 ? 0 : (dv1 < dv2 ? -1 : 1);            default:                long lv1 = longValue(v1);                long lv2 = longValue(v2);                return lv1 == lv2 ? 0 : (lv1 < lv2 ? -1 : 1);            }        }        return result;    }

compareWithConversion方法有两个Object类型的参数v1和v2,带入上面的条件,即

  v1 = param.sendstate(空字符串)

  v2 = 0

经过getNumericType方法的处理,最终进入case=8里面处理,doubleValue方法如下:

public static double doubleValue(Object value) throws NumberFormatException {        if (value == null) {            return 0.0D;        } else {            Class c = value.getClass();            if (c.getSuperclass() == Number.class) {                return ((Number)value).doubleValue();            } else if (c == Boolean.class) {                return (Boolean)value ? 1.0D : 0.0D;            } else if (c == Character.class) {                return (double)(Character)value;            } else {                String s = stringValue(value, true);                return s.length() == 0 ? 0.0D : Double.parseDouble(s);            }        }    }

可以看到,当value = 0 的时候,结果值为0.0,当value为空字符串时,结果值为0.0D

所以dv1 == dv2 结果为true,compareWithConversion方法的最终返回值为0,即相等. 

 

 

转载于:https://www.cnblogs.com/nick-guo-sdly/p/9239721.html

你可能感兴趣的文章
Pycharm中配置Git版本管理
查看>>
手机app测试之我见
查看>>
Fiddler实现移动端手机抓包
查看>>
wps直接打开CVS文件会把长串数字订单号最后4位变为0
查看>>
BPM配置故事之案例8-根据表单数据调整审批线路
查看>>
LeetCode OJ 3Sum 3个整数之和
查看>>
Knockout应用开发指南 第八章:简单应用举例(2)
查看>>
Bootstrap WPF Style,Bootstrap风格的WPF样式
查看>>
Stern-Brocot Tree [HDU 4556]
查看>>
103 Binary Tree Zigzag Level Order Traversal 二叉树的锯齿形层次遍历
查看>>
springboot项目中使用maven resources
查看>>
ubuntu12.04 卸载和安装mysql
查看>>
转:phpStudy for Linux (lnmp+lamp一键安装包)
查看>>
记录项目从无到有
查看>>
博客园文章编辑器【客户端应用程序】V2.0.0发布,命名为51cnblogs
查看>>
C# WPF获取任务栏时间区域的Rectangle
查看>>
DIV+CSS:如何编写代码才能更有效率
查看>>
利用Idea查看类的继承关系图
查看>>
跨进程访问共享内存的权限问题
查看>>
AD管理中心
查看>>