MyBatis中Integer值爲0時,無法作爲判斷條件
1.導語
最近在工作中使用SpringBoot+MyBatis時,遇見一個小問題,代碼如下:
<if test="status != null and status != ''">
Status,
</if>
status是一個Integer類型的參數,當我傳遞值爲0的時候,MyBatis不會把這個條件添加到SQL中。
2.源碼分析
爲什麼會出現上訴的問題呢,我也很困擾,經過排查,發現並不是傳參出現問題,參數能順利的傳遞到mapper層,那麼我們可以推斷,問題是出現在Mybatis源碼中。
根據ITEYE的一位博主的博客,並且通過這位博主的方法,我們追蹤Mybatis的源碼,一直到ExpressionEvaluator這個類,發現在這個類中有如下的方法
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)).equals(BigDecimal.ZERO);
return value != null;
}
在這段代碼裏面,你是不是看到了evaluateBoolean方法的第一行使用了Ognl表達式,通過Ognl表達式,我們可以知道在它的語法中 0 == ’ ’ == false,因此我們寫的是不成立的。由此,我們也得出一個提示,在MyBatis的if判斷中,除了String類型可以和 ’ ’ 進行比較之外,其餘的類型最好都不要與 ’ ’ 作比較,這是一種不規範的寫法。
3.解決方式
3.1
把上面的status != ’ ‘去掉即可
3.2
或者在 status != ’ ‘後面繼續添加 or status == 0
4.總結
針對上述問題,我們最好的方式是採用3.1的處理方法,除了String類型的參數之外,其餘類型不要和 ’ ’ 進行比較。另外,由於Ognl表達式對char類型也有處理,因此我們在做的時候也需要注意:如果你的判斷是 XXX == ‘A’的方式,會出問題,因爲OGNL會把A作爲char類型處理;因此需要改成 XXX == “A”,用雙引號括起來。