Mybatis查詢時的延遲加載解析
Mybatis延遲加載
什么是延遲加載呢?
通俗的講就是按需加載,我們需要什么的時候再去進行什么操作。
什么時候會用到延遲加載呢?
多表單獨查詢的時候。
而且先從單表查詢,需要時再從關(guān)聯(lián)表去關(guān)聯(lián)查詢,能大大提高數(shù)據(jù)庫性能,因為查詢單表要比關(guān)聯(lián)查詢多張表速度要快。 延遲加載分為兩種:深度延時加載,侵入式延遲加載
如何開啟延時加載?
兩種方法:
1.在collection標簽中:
<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,默認開啟深度延遲加載
</resultMap>
<select id="selectByMinorIds" resultType="com.example.mytest01.pojo.Minor" >
select mname from minor where countryid =#{cid}
</select>
2.mybatis.xml中進行配置
<settings> <!--延遲加載總開關(guān),打開后,默認的是深度延時加載 --> <setting name="lazyLoadingEnabled" value="true" /> <!--侵入式延遲加載開關(guān) --> <!--3.4.1版本之前默認是true,之后默認是false --> <setting name="aggressiveLazyLoading" value="true" /> </settings>
加載特點
侵入式延遲: 執(zhí)行對主加載對象的查詢時,不會執(zhí)行對關(guān)聯(lián)對象的查詢。但當要訪問主加載對象的詳情屬性時,就會馬上執(zhí)行關(guān)聯(lián)對象的select查詢。
深度延遲: 執(zhí)行對主加載對象的查詢時,不會執(zhí)行對關(guān)聯(lián)對象的查詢。訪問主加載對象的詳情時也不會執(zhí)行關(guān)聯(lián)對象的select查詢。只有當真正訪問關(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:填寫映射當前的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>
當不開啟延遲加載時:
@Autowired
private IMinorDao m;
@Test
void hah(){
Country c =m.selectByMinorId(1);
//System.out.println(c.getCname());
}

進行兩次查詢;
@Autowired
private IMinorDao m;
@Test
void hah(){
//Country c =m.selectByMinorId(1);
System.out.println(c.getCname());
}

進行兩次查詢;
重點來了: 當開深度啟延遲加載時:
@Autowired
private IMinorDao m;
@Test
void hah(){
Country c =m.selectByMinorId(1);
//System.out.println(c.getCname());
}

通過日志觀察到,只查詢一次,還未進行第二次查詢;
@Autowired
private IMinorDao m;
@Test
void hah(){
//Country c =m.selectByMinorId(1);
System.out.println(c.getCname());
}

當查詢主加載對象的詳情屬性時,依舊只進行了第一次的查詢; .
@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):只有當查詢主加載對象的關(guān)聯(lián)屬性時,才進行了兩次查詢
當開啟侵入式延遲加載時:
@Autowired
private IMinorDao m;
@Test
void hah(){
Country c =m.selectByMinorId(1);
//System.out.println(c.getCname());
}

通過日志觀察到,只查詢一次,還未進行第二次查詢;
@Autowired
private IMinorDao m;
@Test
void hah(){
//Country c =m.selectByMinorId(1);
System.out.println(c.getCname());
}

與深度延遲加載不同的時:當查詢主屬性的詳細信息時,Mybatis就已經(jīng)進行了第二次的關(guān)聯(lián)屬性的查詢;
到此這篇關(guān)于Mybatis查詢時的延遲加載解析的文章就介紹到這了,更多相關(guān)Mybatis延遲加載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實戰(zhàn)之晚會抽獎系統(tǒng)的實現(xiàn)
這篇文章主要介紹了如何利用Java語言編寫一個晚會抽獎系統(tǒng),文中采用到的技術(shù)有Jdbc、Servlert、JavaScript、JQuery、Ajax等,感興趣的可以學(xué)習(xí)一下2022-03-03
Java基礎(chǔ)知識之CharArrayReader流的使用
這篇文章主要介紹了Java基礎(chǔ)知識之CharArrayReader流的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
SpringBoot使用AOP,內(nèi)部方法失效的解決方案
這篇文章主要介紹了SpringBoot使用AOP,內(nèi)部方法失效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08

