mybatis動(dòng)態(tài)sql常用場(chǎng)景總結(jié)
前言
平時(shí)在開(kāi)發(fā)中,針對(duì)動(dòng)態(tài)sql這塊目前是薄弱點(diǎn),自己根據(jù)官網(wǎng)在對(duì)應(yīng)項(xiàng)目邊測(cè)試邊寫(xiě)博客,此篇只是為了加深動(dòng)態(tài)sql的熟練度,有不到之處敬請(qǐng)批評(píng)指正!
1.if
使用動(dòng)態(tài) SQL 最常見(jiàn)情景是根據(jù)條件包含 where 子句的一部分。比如:
<select id="findActiveBlogWithTitleLike"
resultType="Blog">
SELECT * FROM BLOG
WHERE state = ‘ACTIVE'
<if test="title != null">
AND title like #{title}
</if>
</select>
這條語(yǔ)句提供了可選的查找文本功能。如果不傳入 “title”,那么所有處于 “ACTIVE” 狀態(tài)的 BLOG 都會(huì)返回;如果傳入了 “title” 參數(shù),那么就會(huì)對(duì) “title”
一列進(jìn)行模糊查找并返回對(duì)應(yīng)的 BLOG 結(jié)果(細(xì)心的讀者可能會(huì)發(fā)現(xiàn),“title” 的參數(shù)值需要包含查找掩碼或通配符字符)。
如果希望通過(guò) “title” 和 “author” 兩個(gè)參數(shù)進(jìn)行可選搜索該怎么辦呢?首先,我想先將語(yǔ)句名稱(chēng)修改成更名副其實(shí)的名稱(chēng);接下來(lái),只需要加入另一個(gè)條件即可。
<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>
2. choose、when、otherwise
有時(shí)候,我們不想使用所有的條件,而只是想從多個(gè)條件中選擇一個(gè)使用。針對(duì)這種情況,MyBatis 提供了 choose 元素,它有點(diǎn)像 Java 中的 switch 語(yǔ)句。
還是上面的例子,但是策略變?yōu)椋簜魅肓?“title” 就按 “title” 查找,傳入了 “author” 就按 “author” 查找的情形。若兩者都沒(méi)有傳入,
就返回標(biāo)記為 featured 的 BLOG(這可能是管理員認(rèn)為,與其返回大量的無(wú)意義隨機(jī) Blog,還不如返回一些由管理員精選的 Blog)。
<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>
3. trim、where、set
前面幾個(gè)例子已經(jīng)方便地解決了一個(gè)臭名昭著的動(dòng)態(tài) SQL 問(wèn)題。現(xiàn)在回到之前的 “if” 示例,這次我們將 “state = ‘ACTIVE'” 設(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>
</select>
如果沒(méi)有匹配的條件會(huì)怎么樣?最終這條 SQL 會(huì)變成這樣:
SELECT * FROM BLOG WHERE
這會(huì)導(dǎo)致查詢(xún)失敗。如果匹配的只是第二個(gè)條件又會(huì)怎樣?這條 SQL 會(huì)是這樣:
SELECT * FROM BLOG WHERE AND title like ‘someTitle'
這個(gè)查詢(xún)也會(huì)失敗。這個(gè)問(wèn)題不能簡(jiǎn)單地用條件元素來(lái)解決。這個(gè)問(wèn)題是如此的難以解決,以至于解決過(guò)的人不會(huì)再想碰到這種問(wèn)題。
MyBatis 有一個(gè)簡(jiǎn)單且適合大多數(shù)場(chǎng)景的解決辦法。而在其他場(chǎng)景中,可以對(duì)其進(jìn)行自定義以符合需求。而這,只需要一處簡(jiǎn)單的改動(dòng):
<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ì)在子元素返回任何內(nèi)容的情況下才插入 “WHERE” 子句。而且,若子句的開(kāi)頭為 “AND” 或 “OR”,where 元素也會(huì)將它們?nèi)コ?br /> 如果 where 元素與你期望的不太一樣,你也可以通過(guò)自定義 trim 元素來(lái)定制 where 元素的功能。比如,和 where 元素等價(jià)的自定義 trim 元素為:
<trim prefix="WHERE" prefixOverrides="AND |OR "> ... </trim>
prefixOverrides 屬性會(huì)忽略通過(guò)管道符分隔的文本序列(注意此例中的空格是必要的)。上述例子會(huì)移除所有 prefixOverrides 屬性中指定的內(nèi)容,并且插入 prefix 屬性中指定的內(nèi)容。
用于動(dòng)態(tài)更新語(yǔ)句的類(lèi)似解決方案叫做 set。set 元素可以用于動(dòng)態(tài)包含需要更新的列,忽略其它不更新的列。比如:
<update id="updateAuthorIfNecessary">
update Author
<set>
<if test="username != null">username=#{username},</if>
<if test="password != null">password=#{password},</if>
<if test="email != null">email=#{email},</if>
<if test="bio != null">bio=#{bio}</if>
</set>
where id=#{id}
</update>
這個(gè)例子中,set 元素會(huì)動(dòng)態(tài)地在行首插入 SET 關(guān)鍵字,并會(huì)刪掉額外的逗號(hào)(這些逗號(hào)是在使用條件語(yǔ)句給列賦值時(shí)引入的)。
來(lái)看看與 set 元素等價(jià)的自定義 trim 元素吧:
<trim prefix="SET" suffixOverrides=","> ... </trim>
注意,我們覆蓋了后綴值設(shè)置,并且自定義了前綴值。
4. foreach
動(dòng)態(tài) SQL 的另一個(gè)常見(jiàn)使用場(chǎng)景是對(duì)集合進(jìn)行遍歷(尤其是在構(gòu)建 IN 條件語(yǔ)句的時(shí)候)。比如:
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
foreach 元素的功能非常強(qiáng)大,它允許你指定一個(gè)集合,聲明可以在元素體內(nèi)使用的集合項(xiàng)(item)和索引(index)變量。它也允許你指定開(kāi)頭與結(jié)尾的字符串以及集合項(xiàng)迭代之間的分隔符。
這個(gè)元素也不會(huì)錯(cuò)誤地添加多余的分隔符,看它多智能!
提示 你可以將任何可迭代對(duì)象(如 List、Set 等)、Map 對(duì)象或者數(shù)組對(duì)象作為集合參數(shù)傳遞給 foreach。當(dāng)使用可迭代對(duì)象或者數(shù)組時(shí),index 是當(dāng)前迭代的序號(hào),
item 的值是本次迭代獲取到的元素。當(dāng)使用 Map 對(duì)象(或者 Map.Entry 對(duì)象的集合)時(shí),index 是鍵,item 是值。
至此,我們已經(jīng)完成了與 XML 配置及映射文件相關(guān)的討論。下一章將詳細(xì)探討 Java API,以便你能充分利用已經(jīng)創(chuàng)建的映射配置。
到此這篇關(guān)于mybatis動(dòng)態(tài)sql總結(jié)的文章就介紹到這了,更多相關(guān)mybatis動(dòng)態(tài)sql內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- IDEA下創(chuàng)建SpringBoot+MyBatis+MySql項(xiàng)目實(shí)現(xiàn)動(dòng)態(tài)登錄與注冊(cè)功能
- mybatis的動(dòng)態(tài)sql之if test的使用說(shuō)明
- 在Mybatis @Select注解中實(shí)現(xiàn)拼寫(xiě)動(dòng)態(tài)sql
- Mybatis中的動(dòng)態(tài)SQL語(yǔ)句解析
- MyBatis動(dòng)態(tài)Sql之if標(biāo)簽的用法詳解
- mybatis動(dòng)態(tài)sql之Map參數(shù)的講解
- Mybatis下動(dòng)態(tài)sql中##和$$的區(qū)別講解
- MyBatis執(zhí)行動(dòng)態(tài)SQL的方法
相關(guān)文章
Sql Server 2000刪除數(shù)據(jù)庫(kù)備份文件
Sql Server 2000刪除數(shù)據(jù)庫(kù)備份文件的語(yǔ)句。2009-09-09
SQL語(yǔ)句(T-SQL匯總) 用T-SQL畫(huà)出這些圖形
今天和大家一起來(lái)分享一下SQL語(yǔ)句,T-SQL的用法和語(yǔ)法,以及一些例子,目的是幫助大家一起來(lái)復(fù)習(xí)一下T-SQL的基本語(yǔ)句,以便在項(xiàng)目中更快速的運(yùn)用,當(dāng)然對(duì)于新手來(lái)說(shuō)就更應(yīng)該去學(xué)習(xí)和總結(jié)了2012-07-07
mssql中得到當(dāng)天數(shù)據(jù)的語(yǔ)句
mssql中得到當(dāng)天數(shù)據(jù)的語(yǔ)句...2007-08-08
SQL中聚類(lèi)后字段數(shù)據(jù)串聯(lián)字符串方法常見(jiàn)示例代碼
這篇文章主要介紹了SQL中聚類(lèi)后字段數(shù)據(jù)串聯(lián)字符串方法常見(jiàn)的方法,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2025-01-01
在sqlserver數(shù)據(jù)庫(kù)中導(dǎo)入Excel數(shù)據(jù)的全過(guò)程
在SQL Server中導(dǎo)入Excel數(shù)據(jù)可以通過(guò)使用導(dǎo)入/導(dǎo)出向?qū)?lái)完成,下面這篇文章主要給大家介紹了關(guān)于在sqlserver數(shù)據(jù)庫(kù)中導(dǎo)入Excel數(shù)據(jù)的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
一文詳解SQL Server如何跟蹤自動(dòng)統(tǒng)計(jì)信息更新
SQL Server數(shù)據(jù)庫(kù)中,我們都清楚統(tǒng)計(jì)信息對(duì)于優(yōu)化器來(lái)說(shuō)非常重要,所以本文就來(lái)和大家簡(jiǎn)單聊一聊SQL Server如何跟蹤自動(dòng)統(tǒng)計(jì)信息更新吧2025-03-03
Sqlserver之死鎖查詢(xún)以及批量解鎖的實(shí)現(xiàn)方法
這篇文章主要介紹了Sqlserver之死鎖查詢(xún)以及批量解鎖的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
透明數(shù)據(jù)加密(TDE)庫(kù)的備份和還原
對(duì)于包含敏感數(shù)據(jù)的庫(kù),要實(shí)現(xiàn)備份加密。即備份文件別人拿到也不能還原和查看其中的數(shù)據(jù)2012-07-07
SQL Server中判斷和處理NULL值的多種方法和解決方案
在SQL Server數(shù)據(jù)庫(kù)中,NULL是表示缺少數(shù)據(jù)或未知值的特殊標(biāo)記,處理NULL值是SQL開(kāi)發(fā)人員經(jīng)常遇到的問(wèn)題之一,本文將介紹SQL Server中判斷和處理NULL值的不同方法,以及一些解決方案,幫助您更好地處理數(shù)據(jù)庫(kù)中的NULL值情況,需要的朋友可以參考下2024-01-01
sql server實(shí)現(xiàn)遞歸查詢(xún)的方法示例
這篇文章主要介紹了sql server實(shí)現(xiàn)遞歸查詢(xún)的方法,結(jié)合具體實(shí)例形式分析了SQL Server遞歸查詢(xún)的原理與實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-03-03

