Mybatis
的強(qiáng)大特性之一便是它的動(dòng)態(tài)SQL
治力。在實(shí)際開發(fā)中,數(shù)據(jù)庫(kù)的查詢比較復(fù)雜勃黍,需要在不同的邏輯中執(zhí)行不同的SQL語(yǔ)句宵统。我們往往要根據(jù)各種不同的場(chǎng)景拼接出不同的SQL語(yǔ)句,而Mybatis
給我們提供了動(dòng)態(tài)SQL覆获,可以讓我們根據(jù)具體的業(yè)務(wù)邏輯來(lái)拼接SQL語(yǔ)句马澈。(Mybatis采用功能強(qiáng)大的基于OGNL的表達(dá)式來(lái)淘汰其他的大部分元素)
if條件(簡(jiǎn)單的條件判斷)
用戶可以選擇其中的任意某些字段或者都不選,這個(gè)時(shí)候我們的查詢語(yǔ)句該怎么寫呢弄息。 其實(shí)很簡(jiǎn)單痊班,我們只需要寫一些動(dòng)態(tài)的sql就可以實(shí)現(xiàn)這一功能。如下代碼摹量,只需要在拼接查詢條件前辩块,先用<if>
是否為null
,如果不為null
,則執(zhí)行代碼時(shí)會(huì)把條件拼接在<where>
后
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
現(xiàn)在回到“if”示例废亭,這次我們將“ACTIVE = 1”
也設(shè)置成動(dòng)態(tài)的條件国章,看看會(huì)發(fā)生什么。
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG
<where>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</where>
</select>
where 元素只會(huì)在至少有一個(gè)子元素的條件返回 SQL 子句的情況下才去插入“WHERE”子句豆村。而且液兽,若語(yǔ)句的開頭為“AND”或“OR”,where 元素也會(huì)將它們?nèi)コ?/p>
test屬性
test
的屬性用于條件判斷的語(yǔ)句中掌动,它在Mybatis
中廣泛使用四啰。它的作用相當(dāng)于判斷真假。在大部分場(chǎng)景中我們都是用它判斷空和非空粗恢。有時(shí)候我們需要判斷字符串柑晒、數(shù)字和枚舉等。
choose(選擇其中的一項(xiàng))
有時(shí)我們不想應(yīng)用到所有的條件語(yǔ)句眷射,而只想從中擇其一項(xiàng)匙赞。針對(duì)這種情況,MyBatis
提供了 choose
元素妖碉,它有點(diǎn)像 Java 中的switch
語(yǔ)句 我們來(lái)看一個(gè)簡(jiǎn)單的例子:
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
where(簡(jiǎn)化SQL語(yǔ)句中where條件判斷)
在上面的案例中小伙伴們可能都發(fā)現(xiàn)了一個(gè)問(wèn)題涌庭,就是我們?cè)谔砑硬樵儣l件的時(shí)候,在查詢條件之前都先添加了where 1=1
欧宜,然后后面直接在這之后再追加and什么什么的坐榆,那么每次這樣來(lái)寫顯然有點(diǎn)麻煩,有沒有簡(jiǎn)單一點(diǎn)的方案呢冗茸?當(dāng)然有席镀,我們可以通過(guò)where元素簡(jiǎn)化SQL語(yǔ)句中的where條件,如下:
<select id="getUser3" resultMap="u">
SELECT * FROM user2
<where>
<choose>
<when test="id!=null">
AND id=#{id}
</when>
<when test="address!=null">
AND address=#{address}
</when>
<when test="username!=null">
AND user_name LIKE concat(#{username},'%')
</when>
<otherwise>
AND 10>id
</otherwise>
</choose>
</where>
</select>
這樣夏漱,只有where元素中有條件成立愉昆,才會(huì)將where關(guān)鍵字組裝到SQL中,這樣就比前一種方式簡(jiǎn)單許多麻蹋。
trim(替換和添加)
trim
t元素就意味著我們需要去掉一些特殊的字符串跛溉,prefix
代表的語(yǔ)句中的前綴,而prefixOverrides
代表的是你需要去掉的那種字符串扮授,我們可以將and替換為where芳室,如下:
<select id="getUser4" resultMap="map">
SELECT * FROM user2
<!--這個(gè)語(yǔ)句中是把AND換成where,下面的寫法基本與where是等效的-->
<trim prefix="where" prefixOverrides="and">
AND id=1
</trim>
</select>
這個(gè)最終執(zhí)行的sql是SELECT * FROM user2 where id=1
刹勃。
set(主要用于更新)
set是我們?cè)诟卤淼臅r(shí)候使用的元素堪侯,通過(guò)set元素,我們可以逐字段的修改一條數(shù)據(jù)荔仁,如下:
<update id="update">
UPDATE user2
<set>
<if test="username!=null">
user_name=#{username},
</if>
<if test="password!=null">
password=#{password}
</if>
</set>
WHERE id=#{id}
</update>
在set元素中伍宦,如果遇到了逗號(hào)芽死,系統(tǒng)會(huì)自動(dòng)將之去除。
foreach(主要用于IN語(yǔ)句中)
foreach
元素用來(lái)遍歷集合次洼,比如我想查詢多個(gè)城市的人关贵,我的sql語(yǔ)句可能是這樣SELECT * FROM user2 WHERE address IN('西安','北京')
卖毁,我在查詢的時(shí)候可能只是傳入了一個(gè)list集合揖曾,該集合中有西安和北京兩個(gè)查詢條件,那我如何將這個(gè)集合組裝成一個(gè)sql語(yǔ)句呢亥啦?很簡(jiǎn)單炭剪,如下:
<!--foreach用于迭代數(shù)據(jù)的元素
open表示開始的符號(hào)
close表示結(jié)束符號(hào)
seprator表示元素間的分隔符
items表示迭代的數(shù)組
-->
<select id="getUserInCities" resultMap="BaseResultMap">
SELECT * FROM user2
WHERE address IN
<foreach collection="cities" index="index" open="(" separator="," close=")" item="city">
#{city}
</foreach>
</select>
collection
表示傳入的參數(shù)中集合的名稱,index
表示是當(dāng)前元素在集合中的下標(biāo)翔脱,open
和close
則表示如何將集合中的數(shù)據(jù)包裝起來(lái)奴拦,separator
表示分隔符,item
則表示循環(huán)時(shí)的當(dāng)前元素届吁。這樣一段配置最終組合成的sql就是SELECT * FROM user2 WHERE address IN('西安'错妖,'北京')
。
注意 你可以將任何可迭代對(duì)象(如 List瓷产、Set 等)站玄、Map 對(duì)象或者數(shù)組對(duì)象傳遞給
*foreach*
作為集合參數(shù)枚驻。當(dāng)使用可迭代對(duì)象或者數(shù)組時(shí)濒旦,index 是當(dāng)前迭代的次數(shù),item 的值是本次迭代獲取的元素再登。當(dāng)使用 Map 對(duì)象(或者 Map.Entry 對(duì)象的集合)時(shí)尔邓,index 是鍵,item 是值
bind(預(yù)定義變量)
使用bind元素我們可以預(yù)先定義一些變量锉矢,然后在查詢語(yǔ)句中使用梯嗽,如下:
<select id="getUserByName" resultMap="">
<bind name="un" value="username+'%'"></bind>
SELECT* FROM user2 WHERE user_name LIKE #{un}
</select>
OGNL(Object-Graph Navigation Language )表達(dá)式
在Mybatis
的動(dòng)態(tài)SQL和${}形式的參數(shù)中都用到了OGNL表達(dá)式,所以我們有必要了解OGNL的簡(jiǎn)單用法沽损。Mybatis常用的OGNL表達(dá)式如下:
OGNL表達(dá)式 | 含義 |
---|---|
e1 or e2 | |
e1 and e2 | |
e1 == e2 或 e1 eq e2 | |
e1 != e2 或 e1 neq e2 | |
e1 lt e2(小于) | |
e1 lte e2(小于等于灯节,gt(大于),gte(大于等于)) | |
e1 + e2绵估、e1*e2炎疆、e1/e2、e1-e2国裳、e1%e2 | |
!e 或 not e | 非 |
e.method(args) | 調(diào)用對(duì)象方法 |
e.property | 對(duì)象屬性值 |
e1[e2] | 按索引取值(List形入、數(shù)組和) |