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查詢。因為多表連接查詢,本質(zhì)上是對一個表的查詢,對由多個表連接后形成的一張表的查詢,會一次性將多個表的所有信息查詢出來。
二. 直接加載
執(zhí)行完主加載對象的查詢后,馬上執(zhí)行關(guān)聯(lián)對象的select查詢?!?/p>
1)在mybatis主配置文件中,設(shè)置全局屬性lazyLoadingEnabled的值為false,那么對于關(guān)聯(lián)對象的查詢,都將采用直接加載。即在主加載對象查詢后,立即查詢關(guān)聯(lián)對象?!?/p>
<settings> <!-- 關(guān)閉延遲加載 --> <setting name="lazyLoadingEnabled" value="false"/> </settings>
2)實體類:
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處打斷點跟蹤,控制臺打印如下:
發(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處打斷點,控制臺打印如下:
執(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處斷點,控制臺打印如下
執(zhí)行一步到斷點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)文章
在idea中g(shù)it實現(xiàn)里查看歷史代碼方式
這篇文章主要介紹了在idea中g(shù)it里查看歷史代碼的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10Java 語言實現(xiàn)清除帶 html 標(biāo)簽的內(nèi)容方法
下面小編就為大家?guī)硪黄狫ava 語言實現(xiàn)清除帶 html 標(biāo)簽的內(nèi)容方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02Java中l(wèi)ogback?自動刷新不生效的問題解決
本文主要介紹了Java中l(wèi)ogback?自動刷新不生效的問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05Spring Boot 集成Shiro的多realm配置過程
這篇文章主要介紹了Spring Boot 集成Shiro的多realm配置,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10