Mybatis中的延遲加載詳細(xì)解讀
一. 延遲加載
Mybatis中延遲加載又稱為懶加載,是指在進(jìn)行關(guān)聯(lián)查詢時(shí),按照設(shè)置延遲規(guī)則推遲對(duì)關(guān)聯(lián)對(duì)象的select查詢,延遲加載可以有效的減少數(shù)據(jù)庫的壓力。延遲加載僅僅是對(duì)關(guān)聯(lián)對(duì)象的查詢有延遲設(shè)置,對(duì)于主加載對(duì)象都是直接執(zhí)行查詢。
Mybatis根據(jù)關(guān)聯(lián)對(duì)象查詢的select語句的執(zhí)行時(shí)機(jī),分為以下三種:直接加載,侵入式延遲加載,深度延遲加載。
PS:延遲加載的應(yīng)用要求,關(guān)聯(lián)對(duì)象的查詢與主加載對(duì)象的查詢必須是分別進(jìn)行的select語句,不能是使用多表連接所進(jìn)行的select查詢。因?yàn)槎啾磉B接查詢,本質(zhì)上是對(duì)一個(gè)表的查詢,對(duì)由多個(gè)表連接后形成的一張表的查詢,會(huì)一次性將多個(gè)表的所有信息查詢出來。
二. 直接加載
執(zhí)行完主加載對(duì)象的查詢后,馬上執(zhí)行關(guān)聯(lián)對(duì)象的select查詢?!?/p>
1)在mybatis主配置文件中,設(shè)置全局屬性lazyLoadingEnabled的值為false,那么對(duì)于關(guān)聯(lián)對(duì)象的查詢,都將采用直接加載。即在主加載對(duì)象查詢后,立即查詢關(guān)聯(lián)對(duì)象。
<settings>
<!-- 關(guān)閉延遲加載 -->
<setting name="lazyLoadingEnabled" value="false"/>
</settings>2)實(shí)體類:
public class HeadTeacher {
private Integer id;
private String name;
// private Clazz clazz; //這邊不引用,防止關(guān)聯(lián)查詢導(dǎo)致死循環(huán)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "HeadTeacher [id=" + id + ", name=" + name + "]";
}
}
public class Clazz {
private Integer id;
private String className;
private Set<HeadTeacher> headTeacher = new LinkedHashSet<>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public Set<HeadTeacher> getHeadTeacher() {
return headTeacher;
}
public void setHeadTeacher(Set<HeadTeacher> headTeacher) {
this.headTeacher = headTeacher;
}
@Override
public String toString() {
return "Clazz [id=" + id + ", className=" + className + ", headTeacher=" + headTeacher + "]";
}
}3)映射文件
<mapper namespace="com.mybatisdemo.dao.ClazzDao">
<resultMap type="com.mybatisdemo.beans.Clazz" id="clazzMapper">
<id column="id" property="id"/>
<result column="class_name" property="className"/>
<collection property="headTeacher" ofType="com.mybatisdemo.beans.HeadTeacher"
column="head_teacher_id" select="com.mybatisdemo.dao.HeaderTeacherDao.queryHeadTeacherById"/>
</resultMap>
<select id="queryClazzById" parameterType="int" resultMap="clazzMapper">
select id,class_name,head_teacher_id from clazz where id = #{id}
</select>
</mapper>
<mapper namespace="com.mybatisdemo.dao.HeaderTeacherDao">
<resultMap type="com.mybatisdemo.beans.HeadTeacher" id="headTeacherMapper">
<id column="id" property="id"/>
<result column="name" property="name"/>
</resultMap>
<select id="queryHeadTeacherById" parameterType="int" resultMap="headTeacherMapper">
select id,name from head_teacher where id = #{id}
</select>
</mapper>4)測(cè)試類:
@Test
public void testClazz() {
ClazzDao clazzDao = sqlSession.getMapper(ClazzDao.class);
Clazz clazz = clazzDao.queryClazzById(1);
System.out.println(clazz.getClassName()); //1
System.out.println(clazz.getHeadTeacher().size()); //2
}
我們?cè)?處打斷點(diǎn)跟蹤,控制臺(tái)打印如下:

發(fā)現(xiàn)我們?cè)谶M(jìn)行主加載對(duì)象查詢時(shí),也對(duì)關(guān)聯(lián)對(duì)象進(jìn)行了查詢。這就是直接加載。
三. 深度延遲加載
執(zhí)行對(duì)主加載對(duì)象的查詢時(shí),不會(huì)執(zhí)行對(duì)關(guān)聯(lián)對(duì)象的查詢,訪問主加載對(duì)象的詳情也不會(huì)執(zhí)行對(duì)關(guān)聯(lián)對(duì)象的查詢。只有真正訪問關(guān)聯(lián)對(duì)象的詳情時(shí),才會(huì)執(zhí)行對(duì)關(guān)聯(lián)對(duì)象的查詢。
1)mybatis主配置文件
<settings>
<!-- 開啟延遲加載 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 侵入式延遲加載關(guān)閉 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
我們?cè)?處打斷點(diǎn),控制臺(tái)打印如下:

執(zhí)行一步到2處,控制臺(tái)打印如下:

再執(zhí)行一步,控制臺(tái)打印:

即:深度延遲加載就是在查詢關(guān)聯(lián)對(duì)象的詳情時(shí),才會(huì)執(zhí)行對(duì)關(guān)聯(lián)對(duì)象的查詢。
四. 侵入式延遲加載
侵入式延遲加載,就是執(zhí)行對(duì)主加載對(duì)象的查詢時(shí),不會(huì)執(zhí)行對(duì)關(guān)聯(lián)對(duì)象的查詢。但當(dāng)要訪問主加載對(duì)象的詳情時(shí),就會(huì)馬上執(zhí)行關(guān)聯(lián)對(duì)象的查詢。即對(duì)關(guān)聯(lián)對(duì)象的查詢,侵入到了主加載對(duì)象詳情查詢中。
1)mybatis主配置文件
<settings>
<!-- 開啟延遲加載 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 侵入式延遲加載關(guān)閉 -->
<setting name="aggressiveLazyLoading" value="true"/>
</settings>在1處斷點(diǎn),控制臺(tái)打印如下

執(zhí)行一步到斷點(diǎn)2處,控制臺(tái)打印如下

發(fā)現(xiàn)在查詢主加載對(duì)象的詳情時(shí),已經(jīng)侵入進(jìn)行了關(guān)聯(lián)對(duì)象的查詢。
到此這篇關(guān)于Mybatis中的延遲加載詳細(xì)解讀的文章就介紹到這了,更多相關(guān)Mybatis延遲加載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在idea中g(shù)it實(shí)現(xiàn)里查看歷史代碼方式
這篇文章主要介紹了在idea中g(shù)it里查看歷史代碼的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
Java 語言實(shí)現(xiàn)清除帶 html 標(biāo)簽的內(nèi)容方法
下面小編就為大家?guī)硪黄狫ava 語言實(shí)現(xiàn)清除帶 html 標(biāo)簽的內(nèi)容方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02
HttpsURLConnection上傳文件流(實(shí)例講解)
下面小編就為大家?guī)硪黄狧ttpsURLConnection上傳文件流(實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07
Java中l(wèi)ogback?自動(dòng)刷新不生效的問題解決
本文主要介紹了Java中l(wèi)ogback?自動(dòng)刷新不生效的問題解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
Spring Boot 集成Shiro的多realm配置過程
這篇文章主要介紹了Spring Boot 集成Shiro的多realm配置,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10

