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.");
  }

}

手动测试,引入依赖


<dependency>
    <groupId>ognlgroupId>
    <artifactId>ognlartifactId>
    <version>2.7.3version>
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 标签的坑

你可能感兴趣的:(后端,mybatis,java,开发语言)