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.

作者:往霄龙
求其上者得其中,求其中者得其下
原文地址:https://www.cnblogs.com/JQKA/p/13293480.html