】mybatis的if判断单个的字符要写到双引号里面才行,改为 赞 踩 <if test="takeWay == '0'">】mybatis的if判断 单个的字符要写到双引号里面才行,改为<if test='takeWay == "1"'>或者改为<if test="takeWay == '1'.toString() "> .xml文件的部分代码 takeWay == “1”处出错,导致不执行if判断中的sql,运行程序不报错,没有任何提示。去掉takeWay == “1” and 则可执行。对此我百思不得其解, 因为自己有写过如下代码,是没错的。 把<if test="takeWay == '1' and workday != null "> 改为<if test='takeWay == "1" and workday != null '> 或改为<if test="takeWay == '1'.toString() and workday != null ">即可。 原因是:mybatis是用OGNL表达式来解析的,在OGNL的表达式中,’1’会被解析成字符,java是强类型的,char 和 一个string 会导致不等,所以if标签中的sql不会被解析。 总结下使用方法:单个的字符要写到双引号里面或者使用.toString()才行! 使用Mybatis时,常常会判断属性是否为空 POJO Mapper XML 当 当status为Integer类型,并且status值为0时,该if判断却为false。 当status为0时,Mybatis会解析成'' 空字符串。 为了避免这个问题,改成下面这样写,去掉对空字符的判断,就解决了该问题 原因分析 通过Debug MyBatis源码顺藤摸瓜找到了 打开ExpressionEvaluator 类,发现解析表达式使用的是OGNL,如果你使用过古老的Struts框架你应该对它不陌生。通过 跟进去看看,终于找到了解析表达式的方法 至于 Any object can be used where a boolean is required. OGNL interprets objects as booleans like this: 果然,如果对象是一个Number类型,值为0时将被解析为 将表达式修改为 这里有必要再提一个“坑”,如果你有类似于 Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。
mybatis 中 if-test 判断详解_mybatis if test
private Integer status;//状态,可能为0、1、2、3。
status
的值为 0时该where SQL and status = 0
并未正常拼接,也就是说test内的表达式为false
,从而导致查询结果错误。但是,显然该值(Integer :0)!= null也!= ' ',应该为true
才对。<if test="status != null">and status = #{status}</if>
IfSqlNode
类,该类用来处理动态SQL的<if>节点,方法public boolean apply(DynamicContext context)
用来构造节点内的SQL语句。if (evaluator.evaluateBoolean(test, context.getBindings())
该代码便是解析<if test="status !=null and status !=''">
test内表达式的关键,如果表达式为true则拼接SQL,否则忽略。OgnlCache.getValue(expression, parameterObject);
可以看到表达式的值是从缓存中获取的,由此可知MyBatis竟然对表达式也做了缓存,以提高性能。private static Object parseExpression(String expression)
,该方法会先从缓存取值,如果没有便进行解析并放入缓存中,然后调用Ognl.getValue(parseExpression(expression), root)
获得表达式的值。Ognl.getValue(parseExpression(expression), root)
是如何运作的,如果你有兴趣可以自行跟下去一探究竟,本文就不赘述了。到此为止,我们已经知道MyBatis的表达式是用OGNL处理的了,这一点已经够了。下面我们去OGNL官网看看是不是我们的表达式语法有问题从而导致该问题的发生。Interpreting Objects as Booleans
false
,否则为true
,浮点型0.00也是如此。OGNL对于boolean的定义和JavaScript有点像,即'' == 0 == false
。这也就不难理解<if test="status != null and status !=''">and status = #{status}</if>
当status=0时出现的问题了,显然0!=''
是不成立的,导致表达式的值为false。<if test="status != null">and status = #{status}</if>
该问题便迎刃而解。该问题的根源还是来自编码的不规范,只有String类型才需要判断是否!=''
,其他类型完全没有这个必要,可能是开发人员为了省事直接复制上一行拿过来改一改或是所使用的MyBatis生成工具不严谨导致该问题的发生。String str ="A";
<if test="str!= null and str == 'A'">
这样的写法时,你要小心了。因为单引号内如果为单个字符时,OGNL将会识别为Java 中的 char类型,显然String 类型与char类型做==
运算会返回false
,从而导致表达式不成立。解决方法很简单,修改为<if test='str!= null and str == "A"'>
即可。