Mybatis中的延遲加載詳細(xì)解讀
一. 延遲加載
Mybatis中延遲加載又稱為懶加載,是指在進(jìn)行關(guān)聯(lián)查詢時,按照設(shè)置延遲規(guī)則推遲對關(guān)聯(lián)對象的select查詢,延遲加載可以有效的減少數(shù)據(jù)庫的壓力。延遲加載僅僅是對關(guān)聯(lián)對象的查詢有延遲設(shè)置,對于主加載對象都是直接執(zhí)行查詢。
Mybatis根據(jù)關(guān)聯(lián)對象查詢的select語句的執(zhí)行時機(jī),分為以下三種:直接加載,侵入式延遲加載,深度延遲加載。
PS:延遲加載的應(yīng)用要求,關(guān)聯(lián)對象的查詢與主加載對象的查詢必須是分別進(jìn)行的select語句,不能是使用多表連接所進(jìn)行的select查詢。因?yàn)槎啾磉B接查詢,本質(zhì)上是對一個表的查詢,對由多個表連接后形成的一張表的查詢,會一次性將多個表的所有信息查詢出來。
二. 直接加載
執(zhí)行完主加載對象的查詢后,馬上執(zhí)行關(guān)聯(lián)對象的select查詢?!?/p>
1)在mybatis主配置文件中,設(shè)置全局屬性lazyLoadingEnabled的值為false,那么對于關(guān)聯(lián)對象的查詢,都將采用直接加載。即在主加載對象查詢后,立即查詢關(guān)聯(lián)對象。
<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)測試類:
@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
}
我們在1處打斷點(diǎn)跟蹤,控制臺打印如下:

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

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

再執(zhí)行一步,控制臺打?。?/p>

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

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

發(fā)現(xiàn)在查詢主加載對象的詳情時,已經(jīng)侵入進(jìn)行了關(guān)聯(lián)對象的查詢。
到此這篇關(guān)于Mybatis中的延遲加載詳細(xì)解讀的文章就介紹到這了,更多相關(guān)Mybatis延遲加載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java利用JSch實(shí)現(xiàn)SSH遠(yuǎn)程操作的技術(shù)指南
在日常開發(fā)中,許多應(yīng)用需要通過 SSH 協(xié)議遠(yuǎn)程連接服務(wù)器來執(zhí)行命令、上傳或下載文件,JSch是一個功能強(qiáng)大的 Java 庫,它提供了便捷的接口來實(shí)現(xiàn) SSH 連接和其他遠(yuǎn)程管理功能,本文將介紹 JSch 的基本功能,并通過實(shí)際代碼示例幫助您快速上手,需要的朋友可以參考下2025-03-03
Spring在多線程下@Resource注入為null的問題
這篇文章主要介紹了Spring在多線程下@Resource注入為null的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02
Springboot轉(zhuǎn)發(fā)重定向?qū)崿F(xiàn)方式解析
這篇文章主要介紹了springboot轉(zhuǎn)發(fā)重定向?qū)崿F(xiàn)方式解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03
java實(shí)現(xiàn)區(qū)域內(nèi)屏幕截圖示例
這篇文章主要介紹了java截圖示例,需要的朋友可以參考下2014-04-04

