Mybatis 0和''相等解析
Mybatis 0和''相等解析
先把mybatis把0!=null解析为false的代码列出来,之后逐步debug. case 8就是原因。本文最后一张图有debug参数
public static int compareWithConversion(Object v1, Object v2) {
int result;
if (v1 == v2) {
result = 0;
} else {
int t1 = getNumericType(v1);
int t2 = getNumericType(v2);
int type = getNumericType(t1, t2, true);
switch(type) {
case 6:
result = bigIntValue(v1).compareTo(bigIntValue(v2));
break;
case 9:
result = bigDecValue(v1).compareTo(bigDecValue(v2));
break;
case 10:
if (t1 == 10 && t2 == 10) {
if (v1 instanceof Comparable && v1.getClass().isAssignableFrom(v2.getClass())) {
result = ((Comparable)v1).compareTo(v2);
break;
}
throw new IllegalArgumentException("invalid comparison: " + v1.getClass().getName() + " and " + v2.getClass().getName());
}
case 7:
case 8:
double dv1 = doubleValue(v1);
double dv2 = doubleValue(v2);
return dv1 == dv2 ? 0 : (dv1 < dv2 ? -1 : 1);
default:
long lv1 = longValue(v1);
long lv2 = longValue(v2);
return lv1 == lv2 ? 0 : (lv1 < lv2 ? -1 : 1);
}
}
return result;
}
SQL语句
<select id="queryAllUsers" parameterType="java.lang.Integer" resultType="java.util.Map">
select * from user
where del_flag=0
<if test="age !=null and age !=''">
and age=#{age}
</if>
</select>
传入参数0,开始debug
SQL最是由SqlSession
实现类方法执行
1.DefaultSqlSession的selectList加上断点
2.F7进入executor.query
3.F5进入ms.getBoundSql(parameterObject);
继续进入 sqlSource.getBoundSql(parameterObject);
,会跳转到DynamicSqlSource
F7进入MixedSqlNode
,
4.F7进入IfSqlNode
(PS:这里是个循环,也会进入StaticTextSqlNode
,跳过,重点看ifSqlNode)
5.F7进入evaluateBoolean
evaluator.evaluateBoolean(test, context.getBindings())
6.F7进入 OgnlCache.getValue(expression, parameterObject)
7.F7进入Ognl.getValue
8.F7进入node.getValue
9.evaluateGetValueBody
10.进入this.getValueBody
,ASTNotEq
OgnlOps.compareWithConversion
总结
一句话就是,mybtis把0和''都转为double类型进行比较,所以0=='' 是true.