MyBatis 數值型別 where 條件配置的坑

2021-10-02 17:24:32 字數 2555 閱讀 1442

<

select

id="listbyconditions"

parametertype

="studentquery"

resultmap

="baseresultmap"

>

select

<

include

refid

="base_column_list"

/>

from t_student

<

where

>

<

if test

="ids != null and ids.size() > 0"

>

and id in

<

foreach

collection

="ids"

item

="item"

open

="("

close

=")"

separator

=","

>

#

foreach

>

if>

<

if test

="name != null and name != ''"

>

and name like concat('%', #, '%')

if>

<

if test

="*** != null and *** != ''"

>

and *** = #

if>

<

if test

="selfcardno != null"

>

and selfcard_no = #

if>

where

>

select

>

該配置問題出在 這段**,*** 在傳入的引數中是 byte 型別,屬於數值型別,而 *** != '' 適用於字串型別判斷,我們誤將數值型別當成字串型別配置了。

當我們錯誤的配置了 *** 欄位的判斷條件,傳入 *** = 0 時,*** != '' 會返回 false,傳入 *** = 1 時,*** != '' 會返回 true,同樣是傳入數字,為什麼會出現兩種不同的結果呢? 

*** = 0 的執行效果如下圖所示:

*** = 1 的執行效果如下圖所示:

*** = 0 的執行返回內容明顯不是我們需要的結果,下面我們通過原始碼分析來解開這個謎題。

通過原始碼分析篇中的「mybatis 原始碼篇-sql 執行的流程」章節,我們知道 mybatis 執行 sql 最終都會交給 executor 類執行。 

前面的除錯步驟省略,直接進入 cacheexecutor 類的 query 方法。

猜測 mybatis 根據引數和對映配置檔案生成 boundsql 的時候,出現了一些問題。我們一路往下 debug,發現問題出在 mybatis 對 ognl 表示式處理上面。 

org.apache.ibatis.ognl.ognlops#comparewithconversion(object v1, object v2) 該方法在比較 (byte)0 和 "" 時,返回的是 true,也就是該方法認為兩者是相同的,執行結果如下圖所示。

所以,*** = 0 的條件沒有出現在生成的 sql 中。

那麼當 *** = 1 的時候,comparewithconversion(object v1, object v2) 方法的執行結果是怎樣的呢?

修改引數,除錯測試介面,執行結果如下圖所示:

comparewithconversion(object v1, object v2) 方法返回的結果是 false,其實該問題的本質是,org.apache.ibatis.ognl.ognlops#doublevalue(object value) 方法當 value 是空字串時返回 0.0d。

對於數值型別的引數,在配置 where 條件的時候要注意,不能把它當成字串型別判斷,數值型只需要判斷 *** != null 就可以了。

mysql數值型別

通過mysql手冊對mysql的數值資料型別進行了乙個回顧,總結如下 mysql支援所有標準sql數值資料型別。這些型別包括嚴格資料型別 integer smallint decimal numeric,以及近似數值資料型別 float real double precision。關鍵字int是in...

Python 數值型別

python中有三種數值型別 數值型別變數會在賦值時自動建立 示例 a 6 int b 8.8 float c 6j complex要驗證python 物件的型別,可使用type 函式 示例 print type a print type b print type c 整型,是乙個整數,正或負,沒有...

Python 數值型別

1 變數命名規則 推薦 使用 具有固定含義的英語單詞縮寫,srv server skt socket,一般以posix命名規則為主 駝峰命名法 大駝峰 名稱以單詞自動連線,且每個單詞首字母均大寫 小駝峰 類似大駝峰,但每乙個字母小寫 posix寫法 多個單詞用下劃線連線 單詞全小寫 my first...