
【
单个字符必须用双引号引起来. 更改为
.xml文件的部分代码
<insert id="insertDelivery" parameterType="com.zuci.request.DeliveryPreferenceReq"> insert cx_customer_deliverypreference <trim prefix="(" suffix=")" suffixOverrides=","> .... 此处省略 <if test="takeWay == '1' and workday != null "> WORKDAY, </if> .... </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> .... 此处省略 <if test="takeWay == '1' and workday != null "> #{workday, jdbcType=VARCHAR}, </if> .... </trim> </insert>
takeWay ==“ 1”错误,导致在判断时未执行sql,运行程序未报告错误,没有提示. 删除takeWay ==“ 1”并执行. 我对此感到困惑,
因为我写了下面的代码,所以是真的.

<if test="messageType == 'senderReceiveSuccess' "> ...... </if>
参加
更改为
或更改为
原因是: mybatis被OGNL表达式解析. 在OGNL表达式中,“ 1”将被解析为字符,java将被强类型化,char和字符串将导致不平等,因此,如果标记sql in将不会被解析.
用法摘要: 单个字符必须用双引号引起来或使用.toString()!

使用Mybatis时,通常会判断该属性是否为空
POJO
private Integer status;//状态,可能为0、1、2、3。
地图XML
<sql> <trim prefix="where" prefixOverrides="and | or "> //...省略其他 <if test="status != null and status !=''">and status = #{status}</if> <trim prefix="where" prefixOverrides="and | or "> </sql>
当状态值为0时,通常不会对SQLand status = 0进行拼接,即测试中的表达式为false,这会导致查询结果不正确. 但是,显然是该值(整数: 0)! = null也! =”,应该是真的.

当status为Integer类型且status值为0时,if判断为假.
状态为0时,Mybatis将解析为''空字符串.
为避免此问题,请将其更改为如下所示,并删除对空字符的判断以解决该问题
<if test="status != null">and status = #{status}</if>
原因分析
通过Debug MyBatis源代码,我找到了IfSqlNode类,该类用于处理动态SQL

public class IfSqlNode implements SqlNode { private ExpressionEvaluator evaluator; private String test; private SqlNode contents; public IfSqlNode(SqlNode contents, String test) { this.test = test; this.contents = contents; this.evaluator = new ExpressionEvaluator(); } public boolean apply(DynamicContext context) { if (evaluator.evaluateBoolean(test, context.getBindings())) { contents.apply(context); return true; } return false; } }
打开ExpressionEvaluator类c 嵌套类,然后发现解析的表达式使用OGNL. 如果您使用了古老的Struts框架,则应该熟悉它. 通过OgnlCache.getValue(表达式,parameterObject);您可以看到该表达式的值是从缓存中获取的,这表明MyBatis甚至缓存了该表达式以提高性能.
public class ExpressionEvaluator { public boolean evaluateBoolean(String expression, Object parameterObject) { Object value = OgnlCache.getValue(expression, parameterObject); if (value instanceof Boolean) return (Boolean) value; if (value instanceof Number) return !new BigDecimal(String.valueOf(value)).equals(BigDecimal.ZERO); return value != null; }
跟进看看,最后找到了一种解析表达式的方法,该方法是私有静态Object parseExpression(字符串表达式),该方法将首先从缓存中获取值,如果没有,它将被解析并放入缓存,然后调用Ognl.getValue(parseExpression(表达式),根)获取表达式的值.
public class OgnlCache { private static final Map<String, ognl.Node> expressionCache = new ConcurrentHashMap<String, ognl.Node>(); public static Object getValue(String expression, Object root) throws OgnlException { return Ognl.getValue(parseExpression(expression), root); } private static Object parseExpression(String expression) throws OgnlException { try { Node node = expressionCache.get(expression); if (node == null) { node = new OgnlParser(new StringReader(expression)).topLevelExpression(); expressionCache.put(expression, node); } return node; } catch (ParseException e) { throw new ExpressionSyntaxException(expression, e); } catch (TokenMgrError e) { throw new ExpressionSyntaxException(expression, e); } }
关于Ognl.getValue(parseExpression(表达式),根)的工作方式c 嵌套类,如果您有兴趣,可以跟进并查找,本文不再赘述. 到目前为止,我们已经知道MyBatis表达式是使用OGNL处理的,这就足够了. 让我们转到OGNL官方网站,看看我们的表达式语法是否存在问题,并且会发生此问题.
任何需要布尔值的对象都可以使用. OGNL将对象解释为布尔值,如下所示:
果然,如果对象是数字类型,则当值是0时,它将被解析为false,否则为true,浮点类型为0.00. OGNL的布尔值定义类似于JavaScript,即''== 0 == false. 这并不难理解
将表达式修改为
如果您有类似String str =“ A”的文字,则有必要在此处提及另一个“坑”;
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-209989-1.html
严厉打击美国的挑衅行为
但实际利率上浮不再设上限
侦察机配合驶往关岛12海里以内侦查