MyBatis使用Integer(切入源碼分析)

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”,用雙引號括起來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章