mybatis的test坑及解决(不等于‘‘ 且 不等于0)
作者:Lou_Lan
概述
mybatis使用xml过程中我们经常会遇到要进行动态sql的判断,如使用if标签和choose标签中的when标签,都会遇到test条件判断,test的条件判断采用的ognl语句。
我遇到的坑是这样的:
<select id="myFunction"> select * from student where 1=1 <if test="status!=null and status!='' and status==0"> and 2=2 </if> <if test="status!=null and status!='' and status!=0"> and 3=3 </if> </select>
然后当 status=1的时候程序能狗正常运行并添加条件,但是当 status=0的时候死活无法进入第一个条件判断(当时改变了多种写法都不行,当时心中千万个草泥马就过去了)。
问题原因
最后一直跟踪查找原因,终于找到了错误的地方,以及出处。
原因就是如下语句:
status!=null and status!=‘' and status==0
是不成立的,因为status是Integer类型,当进行status!=null和status==0的判断都是没有问题的,但是在判断status!='‘的时候问题就来了,既然这个属性字段是Integer类型如何进行字符串的判空呢?
看这个断点截图,当status参数为0的时候进行判断status!=’‘的判断的时候进入这个位置,由断点的位置可以知道,需要比较的是 0 和 ’‘是否相等,但是这两个数据连类型都不同怎么能相等呢,但是mybatis进行了转换比较,但你的参数类型是不是基础数据类型以及其包装类的时候,他会把你的这个空进行如下转换:
由这个图我们知道,最后这个0被转换为 0.0 ,而这个 ’‘ 被转换为0.0,也就是说这个时候的判断就变成了0.0与0.0的判断。
所以最后在test语句中判断参数值如下
0=='‘ //是成立的
就是成立的。
也就说当我们的status=0的时候进行test的参数判断:
status!=null and status!=‘' and status==0
就变成了
status!=null and status!=0 and status==0
所以这个判断语句永远都不可能成立。
问题解决
既然我们知道了原因,那么解决方案就是写判断语句ognl的时候一定要按照数据类型进行,不要写不属于该参数类型的判断方式。
如下:
status!=null and status==0
这样就可以了。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。