MyBatis動(dòng)態(tài)<if>標(biāo)簽使用避坑指南
前言
MyBatis中的<if>動(dòng)態(tài)SQL標(biāo)簽,常用場(chǎng)景是根據(jù)條件添加WHERE子句。本篇文章將對(duì)<if>動(dòng)態(tài)SQL標(biāo)簽使用中的常見(jiàn)問(wèn)題進(jìn)行演示和總結(jié)。
演示的場(chǎng)景有:if判斷字符串,if判斷數(shù)字。
MyBatis版本:3.5.6
正文
一. if標(biāo)簽判斷字符串
查詢參數(shù)Param如下。
public class Param { private int id; private String level; private int times; private String timestamp; // 省略get和set }
語(yǔ)句如下。
<select id="queryEvents" resultMap="eventResultMap"> SELECT id, e_name, e_times, e_level FROM event WHERE id=#{id} <if test="level != null and level != ''"> AND e_level=#{level} </if> </select>
上述是判斷字符串是否為空(null或者空串),不為空時(shí),為WHERE子句添加額外的條件。
通過(guò)<if>標(biāo)簽判斷字符串是否為空,是<if>標(biāo)簽使用頻率最高的用法,但是有時(shí)也會(huì)通過(guò)<if>標(biāo)簽來(lái)判斷字符串的值,這里有多種寫(xiě)法,下面給出正確寫(xiě)法,推薦寫(xiě)法和錯(cuò)誤寫(xiě)法。
正確寫(xiě)法1
<select id="queryEvents" resultMap="eventResultMap"> SELECT id, e_name, e_times, e_level FROM event WHERE id=#{id} <if test="level == 'secondary'"> AND e_times>10 </if> </select>
注意''單引號(hào)中一定需要是多個(gè)字符,如果只有一個(gè)字符,會(huì)報(bào)錯(cuò)。
正確寫(xiě)法2
<select id="queryEvents" resultMap="eventResultMap"> SELECT id, e_name, e_times, e_level FROM event WHERE id=#{id} <if test="level == 'secondary'.toString()"> AND e_times>10 </if> </select>
這種寫(xiě)法不限制''單引號(hào)中的字符個(gè)數(shù),一個(gè)或多個(gè)都可以。
推薦寫(xiě)法
<select id="queryEvents" resultMap="eventResultMap"> SELECT id, e_name, e_times, e_level FROM event WHERE id=#{id} <if test='level == "secondary"'> AND e_times>10 </if> </select>
推薦外層用單引號(hào),內(nèi)層用雙引號(hào)的寫(xiě)法,能少踩很多坑。
特別注意:錯(cuò)誤寫(xiě)法
<select id="queryEvents" resultMap="eventResultMap"> SELECT id, e_name, e_times, e_level FROM event WHERE id=#{id} <if test="level == 'A'"> AND e_times>10 </if> </select>
這種寫(xiě)法會(huì)報(bào)錯(cuò),因?yàn)橄?#39;A'這種單個(gè)字符的情況會(huì)被判定為字符,所以MyBatis認(rèn)為字符串在與字符做比較,從而報(bào)錯(cuò)。但是如果是'AA'或者'A'.toString() 這種,就會(huì)被判定為字符串,就正常。
二. if標(biāo)簽判斷數(shù)字
查詢參數(shù)Param如下。
public class Param { private int id; private String level; private int times; private String timestamp; // 省略get和set }
語(yǔ)句如下。
<select id="queryEvents3" resultMap="eventResultMap"> SELECT id, e_name, e_times, e_level FROM event WHERE e_level=#{level} <if test="times != null"> AND e_times>#{times} </if> </select>
通過(guò)<if>標(biāo)簽也可以對(duì)數(shù)字判空,同時(shí)<if>標(biāo)簽也可以判斷數(shù)字的值,這里有多種寫(xiě)法,下面給出正確寫(xiě)法,推薦寫(xiě)法和錯(cuò)誤寫(xiě)法。
正確寫(xiě)法1
<select id="queryEvents2" resultMap="eventResultMap"> SELECT id, e_name, e_times, e_level FROM event WHERE e_level=#{level} <if test="times > '10'"> AND e_times>#{times} </if> </select>
注意''單引號(hào)中一定需要是多個(gè)數(shù)字。
正確寫(xiě)法2
<select id="queryEvents2" resultMap="eventResultMap"> SELECT id, e_name, e_times, e_level FROM event WHERE e_level=#{level} <if test="times > '0'.toString()"> AND e_times>#{times} </if> </select>
這種寫(xiě)法不限制''單引號(hào)中的數(shù)字個(gè)數(shù),一個(gè)或多個(gè)都可以。
正確寫(xiě)法3
<select id="queryEvents" resultMap="eventResultMap"> SELECT id, e_name, e_times, e_level FROM event WHERE e_level=#{level} <if test="times > 0"> AND e_times>#{times} </if> </select>
判斷條件可以直接寫(xiě)數(shù)字。
推薦寫(xiě)法
<select id="queryEvents2" resultMap="eventResultMap"> SELECT id, e_name, e_times, e_level FROM event WHERE e_level=#{level} <if test='times > "0"'> AND e_times>#{times} </if> </select>
推薦外層用單引號(hào),內(nèi)層用雙引號(hào)的寫(xiě)法,能少踩很多坑。
錯(cuò)誤寫(xiě)法
<select id="queryEvents" resultMap="eventResultMap"> SELECT id, e_name, e_times, e_level FROM event WHERE e_level=#{level} <if test="times > '0'"> AND e_times>#{times} </if> </select>
'0'這種單個(gè)數(shù)字會(huì)被判定為字符,而字符'0'的ASCII值是48,所以times為49及以上時(shí),才滿足times > '0',所以這里有坑,切記。
總結(jié)
<if>標(biāo)簽的test判斷中,外層用雙引號(hào),內(nèi)層用單引號(hào)時(shí),有如下比較規(guī)則。
- 允許數(shù)字與字符串做比較;
- 允許數(shù)字與字符做比較,但不推薦。數(shù)字與字符做比較時(shí),數(shù)字會(huì)與字符的ASCAII值做比較,容易出錯(cuò);
- 不允許包含字母的字符串與字符做比較。這種情況MyBatis會(huì)直接報(bào)錯(cuò);
- 允許全是數(shù)字的字符串與字符做比較,但不推薦。這種情況全是數(shù)字的字符串會(huì)作為數(shù)字來(lái)與字符的ASCII值來(lái)做比較,容易出錯(cuò)。
而在OGNL表達(dá)式中,如果單引號(hào)''中只有一個(gè)數(shù)字或者字母,那么就會(huì)被解析為字符,這時(shí)就會(huì)導(dǎo)致MyBatis或者比較結(jié)果錯(cuò)誤。
因此推薦<if>標(biāo)簽的test判斷中,外層用單引號(hào),內(nèi)層用雙引號(hào),能夠避免踩坑。
以上就是MyBatis動(dòng)態(tài)<if>標(biāo)簽使用避坑指南的詳細(xì)內(nèi)容,更多關(guān)于MyBatis動(dòng)態(tài)<if>標(biāo)簽的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
通過(guò)Java實(shí)現(xiàn)在Word中創(chuàng)建可填充表單
這篇文章主要為大家詳細(xì)介紹了如何通過(guò)Java代碼,以編程方式在Word中創(chuàng)建可填充表單,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-03-03Tomcat正常啟動(dòng),訪問(wèn)所有頁(yè)面均報(bào)404異常,404異常總結(jié)分析
今天遇到一個(gè)問(wèn)題:Tomcat正常啟動(dòng),訪問(wèn)所有頁(yè)面均報(bào)404異常,究竟該如何解決這個(gè)問(wèn)題呢?下邊小編將為大家介紹一下解決方法,需要的朋友可以參考下2013-07-07Java并發(fā)編程之詳解CyclicBarrier線程同步
在之前的文章中已經(jīng)為大家介紹了java并發(fā)編程的工具:BlockingQueue接口,ArrayBlockingQueue,DelayQueue,LinkedBlockingQueue,PriorityBlockingQueue,SynchronousQueue,BlockingDeque接口,ConcurrentHashMap,CountDownLatch,本文為系列文章第十篇,需要的朋友可以參考下2021-06-06java date類(lèi)與string類(lèi)實(shí)例代碼分享
這篇文章主要介紹了java date類(lèi)與string類(lèi)實(shí)例代碼分享,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01