Mybatis查詢時的延遲加載解析
Mybatis延遲加載
什么是延遲加載呢?
通俗的講就是按需加載,我們需要什么的時候再去進(jìn)行什么操作。
什么時候會用到延遲加載呢?
多表單獨(dú)查詢的時候。
而且先從單表查詢,需要時再從關(guān)聯(lián)表去關(guān)聯(lián)查詢,能大大提高數(shù)據(jù)庫性能,因?yàn)椴樵儐伪硪汝P(guān)聯(lián)查詢多張表速度要快。 延遲加載分為兩種:深度延時加載,侵入式延遲加載
如何開啟延時加載?
兩種方法:
1.在collection標(biāo)簽中:
<select id="selectByMinorId" resultMap="selectMinorMap"> select cid,cname from country where cid =#{id} </select> <resultMap id="selectMinorMap" type="Country"> <id column="cid" property="cid"/> <result column="cname" property="cname"/> <collection column="cid" property="mino" ofType="Minor" select="selectByMinorIds" fetchType="lazy"/> //使用fetch屬性的值為true,默認(rèn)開啟深度延遲加載 </resultMap> <select id="selectByMinorIds" resultType="com.example.mytest01.pojo.Minor" > select mname from minor where countryid =#{cid} </select>
2.mybatis.xml中進(jìn)行配置
<settings> <!--延遲加載總開關(guān),打開后,默認(rèn)的是深度延時加載 --> <setting name="lazyLoadingEnabled" value="true" /> <!--侵入式延遲加載開關(guān) --> <!--3.4.1版本之前默認(rèn)是true,之后默認(rèn)是false --> <setting name="aggressiveLazyLoading" value="true" /> </settings>
加載特點(diǎn)
侵入式延遲: 執(zhí)行對主加載對象的查詢時,不會執(zhí)行對關(guān)聯(lián)對象的查詢。但當(dāng)要訪問主加載對象的詳情屬性時,就會馬上執(zhí)行關(guān)聯(lián)對象的select查詢。
深度延遲: 執(zhí)行對主加載對象的查詢時,不會執(zhí)行對關(guān)聯(lián)對象的查詢。訪問主加載對象的詳情時也不會執(zhí)行關(guān)聯(lián)對象的select查詢。只有當(dāng)真正訪問關(guān)聯(lián)對象的詳情時,才會執(zhí)行對關(guān)聯(lián)對象的 select 查詢。
MyBatis 的延遲加載只是對關(guān)聯(lián)對象的查詢有遲延設(shè)置,對于主加載對象都是直接執(zhí)行查詢語句的。
舉例: mapper.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace:填寫映射當(dāng)前的Mapper接口,所有的增刪改查的參數(shù)和返回值類型, 就可以直接填寫縮寫,不區(qū)分大小寫,直接通過方法名去找類型--> <mapper namespace="com.example.mytest01.dao.IMinorDao"> <select id="selectByMinorId" resultMap="selectMinorMap"> select cid,cname from country where cid =#{id} </select> <resultMap id="selectMinorMap" type="Country"> <id column="cid" property="cid"/> <result column="cname" property="cname"/> <collection column="cid" property="mino" ofType="Minor" select="selectByMinorIds"/> </resultMap> <select id="selectByMinorIds" resultType="com.example.mytest01.pojo.Minor" > select mname from minor where countryid =#{cid} </select> </mapper>
當(dāng)不開啟延遲加載時:
@Autowired private IMinorDao m; @Test void hah(){ Country c =m.selectByMinorId(1); //System.out.println(c.getCname()); }
進(jìn)行兩次查詢;
@Autowired private IMinorDao m; @Test void hah(){ //Country c =m.selectByMinorId(1); System.out.println(c.getCname()); }
進(jìn)行兩次查詢;
重點(diǎn)來了: 當(dāng)開深度啟延遲加載時:
@Autowired private IMinorDao m; @Test void hah(){ Country c =m.selectByMinorId(1); //System.out.println(c.getCname()); }
通過日志觀察到,只查詢一次,還未進(jìn)行第二次查詢;
@Autowired private IMinorDao m; @Test void hah(){ //Country c =m.selectByMinorId(1); System.out.println(c.getCname()); }
當(dāng)查詢主加載對象的詳情屬性時,依舊只進(jìn)行了第一次的查詢; .
@Autowired private IMinorDao m; @Test void hah(){ //Country c =m.selectByMinorId(1); //System.out.println(c.getCname()); System.out.println(c.getMino()); }
看到這里我們會發(fā)現(xiàn):只有當(dāng)查詢主加載對象的關(guān)聯(lián)屬性時,才進(jìn)行了兩次查詢
當(dāng)開啟侵入式延遲加載時:
@Autowired private IMinorDao m; @Test void hah(){ Country c =m.selectByMinorId(1); //System.out.println(c.getCname()); }
通過日志觀察到,只查詢一次,還未進(jìn)行第二次查詢;
@Autowired private IMinorDao m; @Test void hah(){ //Country c =m.selectByMinorId(1); System.out.println(c.getCname()); }
與深度延遲加載不同的時:當(dāng)查詢主屬性的詳細(xì)信息時,Mybatis就已經(jīng)進(jìn)行了第二次的關(guān)聯(lián)屬性的查詢;
到此這篇關(guān)于Mybatis查詢時的延遲加載解析的文章就介紹到這了,更多相關(guān)Mybatis延遲加載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)戰(zhàn)之晚會抽獎系統(tǒng)的實(shí)現(xiàn)
這篇文章主要介紹了如何利用Java語言編寫一個晚會抽獎系統(tǒng),文中采用到的技術(shù)有Jdbc、Servlert、JavaScript、JQuery、Ajax等,感興趣的可以學(xué)習(xí)一下2022-03-03Java基礎(chǔ)知識之CharArrayReader流的使用
這篇文章主要介紹了Java基礎(chǔ)知識之CharArrayReader流的使用,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12SpringBoot使用AOP,內(nèi)部方法失效的解決方案
這篇文章主要介紹了SpringBoot使用AOP,內(nèi)部方法失效的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08