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