MyBatis之關(guān)于動(dòng)態(tài)SQL解讀
MyBatis動(dòng)態(tài)SQL
MyBatis 動(dòng)態(tài)SQL優(yōu)點(diǎn)
MyBatis 的強(qiáng)大特性之一便是它的動(dòng)態(tài) SQL。
如果你有使用 JDBC 或其他類似框架的經(jīng)驗(yàn),你就能體會(huì)到根據(jù)不同條件拼接 SQL 語句有多么痛苦,拼接的時(shí)候要確保不能忘了必要的空格,還要注意省掉列名列表最后的逗號(hào)。
利用動(dòng)態(tài) SQL 這一特性可以徹底擺脫這種痛苦。
1、if
動(dòng)態(tài) SQL 通常要做的事情是有條件地包含 where 子句的一部分,例如
<select id="getByDept" resultType="City"> select * from provice <where> <if test="pid!=null"> pid=#{pid} </if> </where> </select>
當(dāng)滿足if中的條件是就會(huì)把if中條件也加入進(jìn)sql語句中,否則不會(huì)。
例如當(dāng)pid不能與null時(shí),就會(huì)查找provice表中pid為傳入的值的數(shù)據(jù),但是當(dāng)pid=null時(shí),就會(huì)查找provice表中的所有數(shù)據(jù)。
2、choose (when, otherwise)
有些時(shí)候你并不想用到所有條件,但是有時(shí)候你又想用到這個(gè)條件,這個(gè)時(shí)候我們就可以用到choose(when,otherwise),這類似于java中的switch-case。
<select id="findStudentByChoose" resultType="City"> SELECT * from city where 1=1 <choose> <when test="cname!=null and cname!=''"> and cname like concat(concat('%',#{cname}),'%') </when> <when test="pid!=0"> and pid=#{pid} </when> <otherwise> <!-- 這里可以寫,也可以不寫代碼--> </otherwise> </choose> </select>
這里提供了兩種選擇方式,你可以選擇根據(jù)cname來查找,也可以選擇根據(jù)pid來查找,但只要滿足一個(gè)條件,其他條件則自動(dòng)選擇不滿足,這樣也可以避免無意義的查找。
(上面的1=1也可以不寫,但是需要加入其他的東西,下面會(huì)提到)
3、trim(where)
前面例子已經(jīng)合宜地解決了動(dòng)態(tài) SQL 問題,但是看下面的例子
<select id="getByDept" resultType="City"> select * from provice where <if test="pid!=null"> pid=#{pid} and </if> <if test="cname!=null and cname!=''"> and pname like concat(concat('%',#{cname}),'%') </if> </select>
當(dāng)沒有一個(gè)條件滿足時(shí),這會(huì)變成
select * from provice where
這樣的sql語句并不正確,另外當(dāng)?shù)谝粋€(gè)條件不滿足,第二個(gè)條件滿足時(shí)則會(huì)變成
select * from provice where and pname like concat(concat('%',#{cname}),'%')
這個(gè)查詢也會(huì)失敗。
這個(gè)問題不能簡單的用條件句式來解決,這個(gè)時(shí)候我們就可以選擇使用trim(where)
<select id="getByDept" resultType="City"> select * from provice where <trim suffix="" suffixOverrides="and"> <if test="pid!=null"> pid=#{pid} and </if> <if test="cname!=null and cname!=''"> and pname like concat(concat('%',#{cname}),'%') </if> </trim> </select>
where 元素知道只有在一個(gè)以上的if條件有值的情況下才去插入"WHERE"子句。
而且,若最后的內(nèi)容是"AND"或"OR"開頭的,where 元素也知道如何將他們?nèi)コ?/p>
如果 where 元素沒有按正常套路出牌,我們還是可以通過自定義 trim 元素來定制我們想要的功能。
4、foreach
動(dòng)態(tài) SQL 的另外一個(gè)常用的必要操作是需要對(duì)一個(gè)集合進(jìn)行遍歷,通常是在構(gòu)建 IN 條件語句的時(shí)候。
注意 你可以將一個(gè) List 實(shí)例或者數(shù)組作為參數(shù)對(duì)象傳給 MyBatis,當(dāng)你這么做的時(shí)候,MyBatis 會(huì)自動(dòng)將它包裝在一個(gè) Map 中并以名稱為鍵。
List 實(shí)例將會(huì)以"list"作為鍵,而數(shù)組實(shí)例的鍵將是"array"。
例如:
<!--根據(jù)數(shù)組來找--> <select id="findStudentByArray" resultType="City"> SELECT * from city where pid in <foreach collection="array" item="pid" open="(" separator="," close=")"> #{pid} </foreach> </select> <!--根據(jù)列表來找--> <select id="findStudentByList" resultType="City"> select * from city WHERE pid in <foreach collection="list" item="pid" open="(" separator="," close=")"> #{pid} </foreach> </select> <!--根據(jù)map來找--> <select id="findStudentByMap" resultType="City"> SELECT * from city where cname like concat(concat('%',#{cname}),'%') and pid in <!--這里的name則根據(jù)前面?zhèn)魅氲膋ey值來確定--> <foreach collection="name" item="map" open="(" separator="," close=")"> #{map} </foreach> </select>
5、bind
bind 元素可以從 OGNL 表達(dá)式中創(chuàng)建一個(gè)變量并將其綁定到上下文。
例如
<select id="bind" resultType="Provice"> <bind name="pro" value="'%' + _parameter.getTitle() + '%'" /> SELECT * FROM porvice WHERE pid LIKE #{pro} </select>
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- 詳解MyBatis的動(dòng)態(tài)SQL實(shí)現(xiàn)原理
- MyBatis動(dòng)態(tài)SQL、模糊查詢與結(jié)果映射操作過程
- MybatisPlus使用Mybatis的XML的動(dòng)態(tài)SQL的功能實(shí)現(xiàn)多表查詢
- Mybatis使用注解實(shí)現(xiàn)復(fù)雜動(dòng)態(tài)SQL的方法詳解
- Mybatis使用XML實(shí)現(xiàn)動(dòng)態(tài)sql的示例代碼
- 詳解MyBatis特性之動(dòng)態(tài)SQL
- MyBatis映射文件中的動(dòng)態(tài)SQL實(shí)例詳解
- MyBatis中的XML實(shí)現(xiàn)和動(dòng)態(tài)SQL實(shí)現(xiàn)示例詳解
- Mybatis動(dòng)態(tài)Sql標(biāo)簽使用小結(jié)
- Mybatis之動(dòng)態(tài)SQL使用小結(jié)(全網(wǎng)最新)
- MyBatis實(shí)現(xiàn)動(dòng)態(tài)SQL的方法
相關(guān)文章
如何使用Sentry 監(jiān)控你的Spring Boot應(yīng)用
這篇文章主要介紹了如何使用Sentry 監(jiān)控你的Spring Boot應(yīng)用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11SpringCloud Alibaba使用Seata處理分布式事務(wù)的技巧
在傳統(tǒng)的單體項(xiàng)目中,我們使用@Transactional注解就能實(shí)現(xiàn)基本的ACID事務(wù)了,隨著微服務(wù)架構(gòu)的引入,需要對(duì)數(shù)據(jù)庫進(jìn)行分庫分表,每個(gè)服務(wù)擁有自己的數(shù)據(jù)庫,這樣傳統(tǒng)的事務(wù)就不起作用了,那么我們?nèi)绾伪WC多個(gè)服務(wù)中數(shù)據(jù)的一致性呢?跟隨小編一起通過本文了解下吧2021-06-06詳解Spring Boot的GenericApplicationContext使用教程
這篇教程展示了如何在Spring應(yīng)用程序中使用GenericApplicationContext 。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-11-11java.util.Date與java.sql.Date的區(qū)別
這篇文章主要介紹了java.util.Date與java.sql.Date的區(qū)別的相關(guān)資料,需要的朋友可以參考下2015-07-07