mybatis <if>语句标签test中0与““比较失效

遇到问题:mybatis的where动态判断语句if test 遇到int类型为0的数据失效

发生情景:根据用户类型是否为空去更新用户信息,其中user对象的userType属性是Integer类型,当userType为0时并没有更新userType信息

存在问题的sql

<update id="updateUser">
	update t_user set user_name = #{param.userName}
	<if test="param.userType != '' and param.userType != null">
		,user_type = #{param.userType}
	</if>
	where id = #{param.id}
</update>

打印执行sql日志发现,userType为0时,并没有拼接标签中的内容。
上网查找原因解释是mybatis源码里在判断Integer类型时候,默认把0值当做空值来处理

解决方案
1、修改参数类型换为String类型
2、如果仍使用Integer类型不做空串判断

	<if test="param.userType != null">
		,user_type = #{param.userType}
	</if>

重点:MyBatis 会将if标签的test属性使用ExpressionEvaluator测试一下是否为true或者为false,即Mybatis 使用的 Ognl表达式 来获取 test 属性的值

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)).compareTo(BigDecimal.ZERO) != 0;
    }
    return value != null;
  }

  public Iterable<?> evaluateIterable(String expression, Object parameterObject) {
    Object value = OgnlCache.getValue(expression, parameterObject);
    if (value == null) {
      throw new BuilderException("The expression '" + expression + "' evaluated to a null value.");
    }
    if (value instanceof Iterable) {
      return (Iterable<?>) value;
    }
    if (value.getClass().isArray()) {
        // the array may be primitive, so Arrays.asList() may throw
        // a ClassCastException (issue 209).  Do the work manually
        // Curse primitives! :) (JGB)
        int size = Array.getLength(value);
        List<Object> answer = new ArrayList<Object>();
        for (int i = 0; i < size; i++) {
            Object o = Array.get(value, i);
            answer.add(o);
        }
        return answer;
    }
    if (value instanceof Map) {
      return ((Map) value).entrySet();
    }
    throw new BuilderException("Error evaluating expression '" + expression + "'.  Return value (" + value + ") was not iterable.");
  }

}

手动测试,引入依赖

<!-- https://mvnrepository.com/artifact/ognl/ognl -->
<dependency>
    <groupId>ognl</groupId>
    <artifactId>ognl</artifactId>
    <version>2.7.3</version>
</dependency>

public static void main(String[] args) {

    Map<String, Object> objectMap = new HashMap<>();
    objectMap.put("state", 0);
    Object value = OgnlCache.getValue("state == ''", objectMap);
    System.out.println(value);//结果为true
}

关于mybatis源码分析参考此博客:MyBatis if 标签的坑

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值