關於Mybatis動態sql中test的坑點總結
總結Mybatis動態sql中test的坑
在mybatis中要實現動態sql,重要方式就是使用test,通過其中表達式返回的true、false來達到動態sql的拼接。隨著業務的復雜,test中的判斷將會越來越復雜,所以熟悉test中細節處理對動態sql來說尤為重要。
判斷相等的註意點
== 少打一個=
現在我們有一個Integer類型的參數typeId,需要當typeId等於1的時候拼接一串sql,mybatis的xml如下:
<if test="count == 1"> AND ISNULL(t.count) </if>
這段代碼沒問題,但有一個隱藏的風險,假如你少打一個 = 這段test將會始終返回ture這種邏輯錯誤mybatis會吞掉,所以養成判斷時常量寫在前變量寫在後是有必要的習慣,適用於很多語言,這種風格尤其適用像js這類語言,其實java不經常出現這種等價錯誤,不過還是建議養成習慣,因為你以後可能接觸其他語言。
所以如果這樣寫
test="count == 1" //當少打瞭一個等號 test="count = 1"//很不幸,這mybatis擅作主張的處理為返回瞭count,true、false將會由count決定 test="1 == count" //當少打瞭一個等號 test="1 = count" //執行時,mybatis會很友好的給你拋個異常
判斷字符是否相等
現在我們有一個String類型的參數type,需要當type等於字符串AI的時候拼接一串sql,mybatis的xml如下
<if test="type== 'AI' "> AND t.type = 1 </if>
動態sql標簽的小陷阱
現在MyBatis越來越受大傢的喜愛瞭,它的優勢大傢都知道,我就不多說瞭,直接說重點。
MyBatis中提供動態SQL功能,我們可以使用<if><when><where><otherwise><foreach>等等,這樣我們就可以寫出根據條件生成的動態SQL瞭,但是,在這中間,我們經常用到的<if>標簽有一個小誤區,一不小心就會掉下去
下面先舉個正常的例子
<select id="findActiveBlogWithTitleLike" parameterType="Blog" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE' <if test="title != null"> AND title like #{title} </if> </select>
在上面的例子中,當title不等於null時,<if>標簽中間的條件才會被拼接上,這樣,SQL語句就是動態的瞭。
但是,當我們對所有條件進行判斷時,你是否會這樣寫:
<select id="findActiveBlogWithTitleLike" parameterType="Blog" resultType="Blog"> SELECT * FROM BLOG WHERE <if test="userId != null"> state = ‘ACTIVE' </if> <if test="title != null"> AND title like #{title} </if> </select>
沒問題吧?至少語法上不錯的,至少它可以正常生成一個SQL。
但是,不知道你註意到瞭沒,當所有條件都為null的時候,會出現什麼情況?
SELECT * FROM BLOG WHERE
看到瞭吧?這樣的SQL能成功執行麼?
答案當然是NO。
那麼該怎麼辦?那就要記住瞭,當你寫動態SQL時候,先考慮一下會不會產生所有條件都不成立的情況,會不會出現隻有一個WHERE而沒有條件的情況,那麼你要做的就是加一個<where>標簽將所有條件包起來。
<select id="findActiveBlogWithTitleLike" parameterType="Blog" resultType="Blog"> SELECT * FROM BLOG <where> <if test="userId != null"> state = ‘ACTIVE' </if> <if test="title != null"> AND title like #{title} </if> </where> </select>
這樣,當所有條件都不成立時,WHERE也不會被拼上。
這時,有機靈的小夥伴發現瞭,如果第一個條件不成立,第二個成立,那SQL會不會變成這樣?
SELECT * FROM BLOG WHERE AND title like #{title}
這個就放心好瞭,當你用<if>標簽包圍條件後,它會自動去掉AND的。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- 基於mybatis 動態SQL查詢總結
- mybatis動態sql常用場景總結
- mybatis動態SQL if的test寫法及規則詳解
- MyBatis中關於SQL的寫法總結
- Mybatis中xml的動態sql實現示例