Mybatis動(dòng)態(tài)sql超詳細(xì)講解
1、多表關(guān)聯(lián)的嵌套查詢
將一個(gè)多表關(guān)聯(lián)查詢拆分為多次查詢,先查詢主表數(shù)據(jù),然后查詢關(guān)聯(lián)表數(shù)據(jù).
<association property="dept" javaType="Dept" select="findDeptByID" column="dept_id"></association>
(1). select:指定關(guān)聯(lián)查詢對(duì)象的 Mapper Statement ID 為 findDeptByID
(2). column="dept_id":關(guān)聯(lián)查詢時(shí)將 dept_id 列的值傳入 findDeptByID,
并將 findDeptByID 查詢的結(jié)果映射到 Emp 的 dept 屬性中
(3).collection 和 association 都需要配置 select 和 column 屬性,兩者配置方法
相同
2、注解
一般寫在Dao中接口的抽象方法的上面,可以代替簡單的sql操作,比如一個(gè)簡單的增加操作,這個(gè)時(shí)候在對(duì)應(yīng)的mappers映射文件xml中就不需要在寫<insert >標(biāo)簽了。
注:我們使用注解一般是簡單的且只涉及一張表的操作,而涉及多張表的復(fù)雜操作我們還是在xml文件中設(shè)置
注:我們一般在定義類中的屬性時(shí),一般不定義基本類型,如int,我們需要定義成integer類型,即引用類型,因?yàn)橐妙愋偷哪J(rèn)值都為null,這樣在判斷時(shí)就都為null了,就不需要每一種基本類型都使用不同的默認(rèn)值
3、動(dòng)態(tài)sql
MyBatis 的一個(gè)強(qiáng)大的特性之一通常是它的動(dòng)態(tài) SQL 能力。 如果你有使用JDBC 或其他 相似框架的經(jīng)驗(yàn),你就明白條件地串聯(lián) SQL 字符串在一起是多么 的痛苦,確保不能忘了空格或在列表的最后省略逗號(hào)。動(dòng)態(tài) SQL 可以徹底處理 這種痛苦。
Mybatis實(shí)現(xiàn)動(dòng)態(tài)sql的關(guān)鍵字有:
1.if where
<if>標(biāo)簽會(huì)對(duì)傳入的條件進(jìn)行判斷 ,如果滿足條件,就將if標(biāo)簽中的sql語句與前面的sql語句進(jìn)行拼接,不滿足則跳過。
<where>標(biāo)簽會(huì)進(jìn)行判斷,如果它包含的子標(biāo)簽(一般是if)又返回值,就會(huì)在其前面插入一個(gè)‘where’,于此同時(shí),他還會(huì)根據(jù)情況將子標(biāo)簽前面的and和or進(jìn)行剔除
舉例:
2.trim
<trim> 標(biāo)簽的功能是可以實(shí)現(xiàn)代替其他標(biāo)簽的功能,但同時(shí)又比其他標(biāo)簽更加靈活
比如通過設(shè)置它的屬性就可以實(shí)現(xiàn)where標(biāo)簽的功能
他有四個(gè)標(biāo)簽,分別是:prefix,prefixOverrides,suffix,suffixOverrides
若有<trim>子句</trim>:
prefix,suffix 是將其屬性值分別放在子句之前和之后。
prefixOverrides,suffixOverrides是刪除子句首和子句尾的指定內(nèi)容。
例如where標(biāo)簽用trim來實(shí)現(xiàn)如下:
<trim prefix="WHERE" prefixOverrides="AND |OR "> ...</trim>
3.choose when otherwise
choose標(biāo)簽實(shí)現(xiàn)多路選擇,當(dāng)choose下的when標(biāo)簽條件滿足時(shí),就將when中的sql拼進(jìn)外面的sql,反之若不滿足,則將下面的otherwise標(biāo)簽中的sql拼進(jìn)總sql。
例如:
4.set
<set>標(biāo)簽是在我們進(jìn)行update操作時(shí)使用。<set>子句</set>
它可以為我們刪除子句尾的',',當(dāng)子句中有內(nèi)容時(shí),會(huì)自生成set在子句首。
同樣的,set標(biāo)簽也可以使用trim標(biāo)簽來代替,
<trim prefix="SET" suffixOverrides=","> 子句</trim>
意思就是當(dāng)子句中有內(nèi)容時(shí),會(huì)在子句首生成set,反之不生成;然后就是在刪除字句尾的','
5.foreach
foreach標(biāo)簽的使用場(chǎng)景是對(duì)集合進(jìn)行遍歷,并可以自定義的設(shè)置
foreach 元素的功能非常強(qiáng)大,它允許你指定一個(gè)集合,聲明可以在元素體內(nèi)使用的集合項(xiàng)(item)和索引(index)變量。它也允許你指定開頭與結(jié)尾的字符串以及各個(gè)元素之間的分隔符。這個(gè)元素也不會(huì)錯(cuò)誤地添加多余的分隔符,看它多智能!
例如:
最終效果是:select * from student where no in (100,101)
4、特殊符號(hào)處理
在 mybatis 中的 xml 文件中,存在一些特殊的符號(hào),比如:<、>、"、&、<> 等,正常書寫 mybatis 會(huì)報(bào)錯(cuò),需要對(duì)這些符號(hào)進(jìn)行轉(zhuǎn)義。具體轉(zhuǎn)義如下所示:
除了可以使用上述轉(zhuǎn)義字符外,還可以使用<![CDATA[]]>來包裹特殊字符。如
下所示:
<if test="id != null"> AND <![CDATA[ id <> #{id} ]]> </if>
<![CDATA[ ]]>是 XML 語法。在 CDATA 內(nèi)部的所有內(nèi)容都會(huì)被解析器忽略。但是有個(gè)問題那就是 <if> </if> <where> </where>
<choose> </choose> <trim> </trim> 等這些標(biāo)簽都不會(huì)被解析,所以 我們只把有特殊字符的語句放在 <![CDATA[ ]]> 盡量縮小<![CDATA[ ]]> 的范圍。
5、Mybatis緩存
Mybatis緩存的作用是為了減輕數(shù)據(jù)庫的壓力,提高查詢性能。緩存實(shí)現(xiàn)的原理是從數(shù)據(jù)庫中查出來的對(duì)象不刪除,而是將其存儲(chǔ)在緩存中,當(dāng)我們?cè)俅尾樵儾樵兺瑯拥膶?duì)象時(shí),就直接調(diào)用緩存中的對(duì)象,不再向數(shù)據(jù)庫執(zhí)行select,減少了數(shù)據(jù)庫的使用頻率,從而提高了數(shù)據(jù)庫的性能。
Mybatis中有一級(jí)緩存和二級(jí)緩存
(1)一級(jí)緩存
一級(jí)緩存的作用域是一個(gè)sqlsession對(duì)象,第一次查詢數(shù)據(jù)時(shí)會(huì)保存到sqlsession對(duì)象中,第二次如果查詢相同的數(shù)據(jù),則直接從sqlsession獲取,直接獲取的前提是這期間這個(gè)對(duì)象中的數(shù)據(jù)沒有改變,即增刪改操作;反之,若有改變,則會(huì)自動(dòng)清除sqlsession緩存,重新進(jìn)行查詢,這并不代表我們關(guān)閉了sqlsession。
消除sqlsession緩存的方式(清除緩存并不代表著關(guān)閉sqlsession):
1.存儲(chǔ)期間數(shù)據(jù)發(fā)生改變,自動(dòng)清除緩存;
2.手動(dòng)清除:sqlsession.clearCache();
sqlsession關(guān)閉時(shí)會(huì)清除緩存。
(2)二級(jí)緩存
二級(jí)緩存是多個(gè)sqlsession共享的,是sqlsession factory 級(jí)別的,根據(jù) mapper 的 namespace 劃分區(qū)域 的,相同 namespace 的 mapper 查詢的數(shù)據(jù)緩存在同一個(gè)區(qū)域,如果使用 mapper 代理方法每個(gè) mapper 的 namespace 都不同,此時(shí)可以理解為二級(jí)緩 存區(qū)域是根據(jù) mapper 劃分。
每次查詢會(huì)先從緩存區(qū)域查找,如果找不到則從數(shù)據(jù)庫查詢,并將查詢到數(shù)據(jù)寫 入緩存。Mybatis 內(nèi)部存儲(chǔ)緩存使用一個(gè) HashMap,key 為 hashCode+sqlId+Sql 語句。value 為從查詢出來映射生成的 java 對(duì)象。
sqlSession 執(zhí)行 insert、update、delete 等操作 commit 提交后會(huì)清空緩存區(qū)域,防止臟讀數(shù)據(jù)。
(3)二級(jí)緩存的配置
1.在全局配置文件中的<settings>目錄下啟用二級(jí)緩存,
如下代碼所示,當(dāng) cacheEnabled 設(shè)置為 true 時(shí)啟用二級(jí)緩存,設(shè)置為 false 時(shí)禁用二級(jí)緩存。
<setting name="cacheEnabled" value="true"/>
2、讓我們的model包中的各個(gè)類(admin,student,grade)都實(shí)現(xiàn)序列化接口 Java.io. Serializable。
3、配置映射文件,在 Mappers 各個(gè)映射文件中添加<cache />,表示此 mapper 開啟二級(jí)緩存。 當(dāng) SqlSeesion 關(guān)閉時(shí),會(huì)將數(shù)據(jù)存入到二級(jí)緩存.
注:cache會(huì)有一些屬性,例如:
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
這個(gè)更高級(jí)的配置創(chuàng)建了一個(gè) FIFO 緩存,每隔 60 秒刷新,最多可以存儲(chǔ)結(jié)果對(duì)象或列表的 512 個(gè)引用,而且返回的對(duì)象被認(rèn)為是只讀的,因此對(duì)它們進(jìn)行修改可能會(huì)在不同線程中的調(diào)用者產(chǎn)生沖突。
eviction中屬性可用清除策略有:
LRU
– 最近最少使用:移除最長時(shí)間不被使用的對(duì)象。FIFO
– 先進(jìn)先出:按對(duì)象進(jìn)入緩存的順序來移除它們。SOFT
– 軟引用:基于垃圾回收器狀態(tài)和軟引用規(guī)則移除對(duì)象。WEAK
– 弱引用:更積極地基于垃圾收集器狀態(tài)和弱引用規(guī)則移除對(duì)象。
默認(rèn)的清除策略是 LRU。
總結(jié)
到此這篇關(guān)于Mybatis動(dòng)態(tài)sql的文章就介紹到這了,更多相關(guān)Mybatis動(dòng)態(tài)sql內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
netty?pipeline中的inbound和outbound事件傳播分析
這篇文章主要為大家介紹了netty?pipeline中的inbound和outbound事件傳播分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04Springboot啟動(dòng)擴(kuò)展點(diǎn)超詳細(xì)教程小結(jié)
這篇文章主要介紹了Springboot啟動(dòng)擴(kuò)展點(diǎn)超詳細(xì)教程小結(jié),本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07springboot druid數(shù)據(jù)庫連接池連接失敗后一直重連的解決方法
本文主要介紹了springboot druid數(shù)據(jù)庫連接池連接失敗后一直重連的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04通過JDK源碼學(xué)習(xí)InputStream詳解
InputStream抽象類是所有字節(jié)輸入流的類的超類。這篇文章主要給大家介紹了關(guān)于通過JDK源碼學(xué)習(xí)InputStream的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11SpringMVC?RESTFul實(shí)體類創(chuàng)建及環(huán)境搭建
這篇文章主要為大家介紹了SpringMVC?RESTFul實(shí)體類創(chuàng)建及環(huán)境搭建詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05Spring Boot ActiveMQ發(fā)布/訂閱消息模式原理解析
這篇文章主要介紹了Spring Boot ActiveMQ發(fā)布/訂閱消息模式原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07Java實(shí)戰(zhàn)練習(xí)之撲克牌魔術(shù)
這篇文章主要介紹了Java實(shí)戰(zhàn)練習(xí)之撲克牌魔術(shù),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下2021-04-04