【MyBatis使用】mapper.xml 文件内<if test>标签判断参数值不等于null和空 当参数值为 0 时筛选条件失效原因分析(源码探究)
這個(gè)問(wèn)題有不少小伙伴遇到過(guò),也給出了解決方案,但是沒有探究原因,這次讀一下源碼,看看原因在哪里。
1. 條件失效情況復(fù)現(xiàn)
- Mapper.xml內(nèi)的動(dòng)態(tài)SQL如下【偽代碼】
- 調(diào)用動(dòng)態(tài)SQL的方法如下【偽代碼主要是顯示一下傳遞的參數(shù)值】
查看查詢結(jié)果會(huì)發(fā)現(xiàn)對(duì) viewId 沒有進(jìn)行篩選。
2. 解決方法
去掉判斷條件 and viewId != '' 即可。
<select id="getInfoList" parameterType="java.util.Map" resultType="java.util.Map">SELECT*${schemaName}${tableName}<where><if test="viewId != null">AND viewid = #{viewId}</if></where></select>3. 源碼解析
到底是為什么呢?我們找到 Mybatis 的 IfSqlNode 對(duì)象:
下邊是打斷點(diǎn)進(jìn)行的參數(shù)追蹤:
evaluator.evaluateBoolean(test, context.getBindings()) 為 true 時(shí)當(dāng)前節(jié)點(diǎn)才會(huì)被應(yīng)用。
進(jìn)入 evaluateBoolean(test, context.getBindings()) 方法。
進(jìn)入 OgnlCache.getValue(expression, parameterObject) 方法。
關(guān)鍵方法出現(xiàn)了:Ognl.getValue(parseExpression(expression), context, root);
我們找到 Ognl.getValue(parseExpression(expression), context, root)方法。
中間省略了部分方法,省略的方法主要是查找參數(shù)名稱和參數(shù)值,不重要故未貼出。還有判斷節(jié)點(diǎn)類型的過(guò)程,例子中用的的都是不等于類型的節(jié)點(diǎn)。下邊的方法真正開始對(duì)表達(dá)式兩側(cè)的數(shù)值進(jìn)行比較了。前半段的 viewId != null 不再貼出,只截圖有問(wèn)題的后半段:
進(jìn)入最核心的方法比較方法 compareWithConversion(Object v1, Object v2)
看一下轉(zhuǎn)換的過(guò)程:
問(wèn)題的核心代碼:
public static double doubleValue(Object value) throws NumberFormatException {if (value == null) {return 0.0D;} else {Class c = value.getClass();if (c.getSuperclass() == Number.class) {return ((Number)value).doubleValue();} else if (c == Boolean.class) {return (Boolean)value ? 1.0D : 0.0D;} else if (c == Character.class) {return (double)(Character)value;} else {String s = stringValue(value, true);return s.length() == 0 ? 0.0D : Double.parseDouble(s);}}}由于 "".length() = 0,傳遞的參數(shù) viewId 值是 0?? 時(shí) viewId != '' 就變成 0.0 != 0.0 這個(gè)自然是 false 此時(shí),篩選條件不起作用就不足為奇了。
為什么會(huì)出現(xiàn)這種情況?是框架問(wèn)題嗎? 感覺不是的,我們?cè)诰幊痰臅r(shí)候,對(duì)數(shù)值類型值的判斷本身就不應(yīng)該使用 =='' 或者 !=''這樣的條件。
總結(jié)
以上是生活随笔為你收集整理的【MyBatis使用】mapper.xml 文件内<if test>标签判断参数值不等于null和空 当参数值为 0 时筛选条件失效原因分析(源码探究)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【Java报错】MultipartFil
- 下一篇: 【Java报错】记录一次调用递归方法导致