Mybatis+0+null,小問題引發的血案
Mybatis在進行<if test="status != null and status != ``">
判空操作時,如果status為0的時候,該判斷條件的值為false,也就是說Mybatis此時把0作為null來進行判斷的,所以遇到這種情況時,只能按照下面這個方法來辦!
一、原始碼調查結果
遇到這個問題時,我翻看了Mybatis的原始碼,發現其在ExpressionEvaluator.java類的evaluateBoolean方法處返回了false,這個原始碼包的分析方式和原始碼分析 There is no getter for property named ‘*’ in ‘class java.lang.String有極大的相同之處。
但發現了問題,也然並卵,修改Mybatis的原始碼我是不行,所以只能曲線救國!
二、場景分析
資料庫欄位
`status` tinyint(2) NOT NULL COMMENT `0未支付,1已支付`,
此時0表示未支付,1表示支付,那麼按照一般的邏輯來看,查詢語句需要寫成這樣的形式:
select * from ym_deals y WHERE d.deal_id = 1
<if test="status != null and status != ``">
and y.status = #{status}
</if>
其意義在於,當查詢引數不傳遞未支付或者支付條件時,就需要查詢status為0和1的全部結果,也就是說沒有條件and y.status = #{status}
,但事實就糾結了,當status傳遞的引數為1時,if條件的結果為true,也就是說sql語句變成了select * from ym_deals y WHERE d.deal_id = 1 and y.status=1
,查詢結果正常,但如果status為0此時,sql語句變成了select * from ym_deals y WHERE d.deal_id = 1
,與預期結果select * from ym_deals y WHERE d.deal_id = 1 and y.status=0
顯然是不符的!
也就是說,Mybatis自作主張的把status為0的條件當做了if的false結果!
三、解決辦法
①、對傳遞引數攔截
public static int parseStringToInt(Object parameter, int defualtValue) {
try {
if ((parameter == null) || (parameter.equals(""))) {
return defualtValue;
}
return Integer.parseInt(parameter.toString());
} catch (Exception ex) {
}
return 0;
}
vo.addParams("status", StrUtil.parseStringToInt(vo.getParams("status"), -1));
也就是說在查詢所有支付狀態的訂單時,把status的值轉換為-1.
②、重構Mybatis的查詢語句
select * from ym_deals y WHERE d.deal_id = 1
<if test="status != -1">
and y.status = #{status}
</if>
此時不再判空,而判-1。
按照以上的辦法就解決了問題,不知道你那是否有更好的解決辦法?
四、後記
這篇文章發表之後,有熱心的朋友給出下面的解決辦法:
lengjian68 status是Integer 型別的 把status!=‘’ 給去掉
去掉就好了1樓 qq_30159115 確定是 int型別的就不用 判斷 status != ‘’ 就搞定了
Re: Optimistic_ 發表 回覆qq_30159115:給力啊!感謝!
判斷不是為空,對於int型別就是在判斷不為0麼?
按照朋友給出的觀點,我嘗試了一下,結果如朋友所說,status確定為integer型別的,把status!=”給去掉就好了。
那麼現在重新來看,我本來的做法就有問題,integer型別的,我幹嘛要用status!=”來進行判斷,這顯然是一種不負責任的做法,至於<if test="status != null and status != ``">
的判斷條件,顯然是錯誤的,從原則上來講,該判斷條件只能來判斷status為string型別的,用來判斷integer型別,豈不貽笑大方,至於後面我提出的解決方案,顯然也就無力蒼白,我只想把這篇文章立馬刪掉,好不再誤導他人。
但看到
Re: Optimistic_ 發表 回覆qq_30159115:給力啊!感謝!
判斷不是為空,對於int型別就是在判斷不為0麼?
下面這位朋友的疑問,我覺得,這篇文章存在還有一些價值,因為還有和我一樣的朋友在犯錯,“判斷不是為空,對於int型別就是在判斷不為0麼?”這種認識顯然是另外一種錯誤,integer型別很明視訊記憶體在為null的情況,那麼對於int型別當然不是在判斷為0的。(當然了,這位仁兄說int型別,在嚴格意義上講,就不存在null的可能了,那麼我只能武斷的推測任務,這位朋友是在說integer,請原諒我的魯莽)
那麼得出以下結論:
-
<if test="status != null">
中status為integer型別的,status=0的判斷結果為true。 -
<if test="status != null and status != ``">
中status為integer型別的,status=0的判斷結果為false,mybatis把status作為了string來進行判斷。 - 如果status為integer,提前對status進行去空操作,再判斷
<if test="status != -1">
在有的時候也是一種曲線救國。
相關文章
感謝您閱讀【沉默王二的部落格】,如果王二的部落格給您帶來一絲幫助或感動,我(也就是王二)將不甚榮幸。
如果您碰巧喜歡,可以留言或者私信我,這將是我鼓搗更多優秀文章的最強動力。
相關文章
- 一個 Handler 面試題引發的血案!!!面試題
- 一道面試題引發的“血案”面試題
- .Net版本引發的血案
- RestTemplate超時引發的血案REST
- JDBC亂碼引發的"血案"JDBC
- SwipeRefreshLayout 引發的一場血案
- vue watch陣列引發的血案Vue陣列
- _nop_()函式引發的血案函式
- Flutter 中由 BuildContext 引發的血案FlutterUIContext
- Maven依賴版本號引發的血案Maven
- 一個map函式引發的血案函式
- PHP array_column 引發的一個小問題PHP
- 一個微信面試題引發的血案 --[譯] 什麼阻塞了 DOM?面試題
- async,await與forEach引發的血案AI
- js正則全域性匹配引發的血案JS
- 一個ES設定操作引發的“血案”
- 實戰|一個表白牆引發的“血案”
- 一場由postcss-bem引發的血案CSS
- 一個全形空格引發Jquery取值的“血案”jQuery
- #iOS AF上傳圖片引發的血案iOS
- alter index rebuild online引發的血案IndexRebuild
- 【RMAN】Oracle_rman中skip引發的血案Oracle
- 一場 Kafka CRC 異常引發的血案Kafka
- 【原創】一對雙引號引發的goldengate血案Go
- MySQL 中一個雙引號的錯位引發的血案MySql
- 做面試的不倒翁:一道事件迴圈題引發的血案面試事件
- 一個系統BUG引發的血案 -- FKDownloader
- 斷點除錯之壓縮引發的血案斷點除錯
- 關於 http cache 的一個小問題以及引發的思考HTTP
- [WCF]缺少一行程式碼引發的血案行程
- 控制檔案不一致引發的“血案”
- 事故現場:MySQL 中一個雙引號的錯位引發的血案MySql
- 一場版本升級引發的效能血案的追凶過程
- reflow和repaint引發的效能問題AI
- 專案叢集引發的問題
- git merge使用不當引發的程式碼丟失血案Git
- 一個由line-height引發的血案與思考
- iOS土味兒講義(一)--一個Button引發的血案iOS