Mybatis中的延遲加載,以及原理分析
Mybatis延遲加載原理
Mybatis 僅支持 association 關(guān)聯(lián)對(duì)象和 collection 關(guān)聯(lián)集合對(duì)象的延遲加載,association 指的就是一對(duì)一,collection 指的就是一對(duì)多查詢。
在 Mybatis配置文件中,可以配置是否啟用延遲加載 lazyLoadingEnabled=true|false。
它的原理是:使用 CGLIB 創(chuàng)建目標(biāo)對(duì)象的代理對(duì)象,當(dāng)調(diào)用目標(biāo)方法時(shí),進(jìn)入攔截器方法,比如調(diào)用 a.getB().getName(),攔截器 invoke()方法發(fā)現(xiàn) a.getB()是null 值,那么就會(huì)單獨(dú)發(fā)送事先保存好的查詢關(guān)聯(lián) B 對(duì)象的 sql,把 B 查詢上來(lái),然后調(diào)用 a.setB(b),于是 a 的對(duì)象 b 屬性就有值了,接著完成 a.getB().getName()方法的調(diào)用。這就是延遲加載的基本原理。
當(dāng)然了,不光是 Mybatis,幾乎所有的包括 Hibernate,支持延遲加載的原理都是一樣的。
MyBatis延遲加載(以及可能會(huì)碰到的一些問(wèn)題)
剛好學(xué)了延遲加載就來(lái)做個(gè)記錄
延遲加載(懶加載) 首先需要配置Mybaits-config文件
<!-- 延遲加載設(shè)置--> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/>
1.單端關(guān)聯(lián)查詢t添加select 需要在RoleDao中添加findRoleById方法,可無(wú)參數(shù)
Role findRoleById(int roleId); //RoleDao中添加 <!-- 延遲加載(懶加載)--> <resultMap id="lazyMap" type="com.demo.entity.User"> <id column="id" property="id"/> <result column="username" property="username"/> <result column="password" property="password"/> <association property="role" column="role_id" select="com.demo.dao.RoleDao.findRoleById"> 需要在RoleDao里面添加findRoleById方法 </association> </resultMap> <select id="findList" resultMap="lazyMap" > select id, username, password, role_id 對(duì)應(yīng)association.column from tb_users </select>
對(duì)應(yīng)的resultMap配置
<resultMap id="roleMap2" type="com.demo.entity.Role"> <id column="id" property="id"/> <result column="role_name" property="roleName"/> <result column="role_state" property="roleState"/> </resultMap> <select id="findRoleById" resultMap="roleMap2"> select id, role_name, role_state from tb_role where id = #{role_id} </select>
測(cè)試 正常 輸出關(guān)聯(lián)對(duì)象會(huì)出現(xiàn)多條SQL
List<User> list = mapper.findList(); for (User user : list) { System.out.println(user.getId() + ", " + user.getUsername() + ", " + user.getPassword() ); System.out.println(user.getRole().getId() + ", "+ user.getRole().getRoleName()); }
心得
使用MyBatis3.4.6版本會(huì)出現(xiàn) lazy proxy.這是MyBatis版本問(wèn)題,之后我把他換成3.5.1之后可以正常運(yùn)行。
如:出現(xiàn)一些其他異常對(duì)應(yīng)的column值寫錯(cuò)了,要一一對(duì)應(yīng) 初學(xué)者設(shè)置column和property最好使用復(fù)制粘貼的方式以免出現(xiàn)其他錯(cuò)誤
優(yōu)點(diǎn):使用延遲加載能夠在不需要關(guān)聯(lián)數(shù)據(jù)的時(shí)候,僅執(zhí)行一條sql 提高執(zhí)行速度(我的理解,如有不對(duì)請(qǐng)多指點(diǎn))
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- MyBatis高級(jí)映射學(xué)習(xí)教程
- MyBatis高級(jí)映射和查詢緩存
- Mybatis高級(jí)映射、動(dòng)態(tài)SQL及獲得自增主鍵的解析
- mybatis高級(jí)映射一對(duì)多查詢實(shí)現(xiàn)代碼
- 基于mybatis高級(jí)映射多對(duì)多查詢的實(shí)現(xiàn)
- javaMybatis映射屬性,高級(jí)映射詳解
- 解析Mybatis延遲加載問(wèn)題
- MyBatis延遲加載與立即加載案例教程
- MyBatis高級(jí)映射ResultMap解決屬性問(wèn)題
- MyBatis實(shí)現(xiàn)高級(jí)映射的示例代碼
- 詳解MyBatis延遲加載是如何實(shí)現(xiàn)的
- MyBatis高級(jí)映射及延遲加載的實(shí)現(xiàn)
相關(guān)文章
java基礎(chǔ)詳解之?dāng)?shù)據(jù)類型知識(shí)點(diǎn)總結(jié)
這篇文章主要介紹了java基礎(chǔ)詳解之?dāng)?shù)據(jù)類型知識(shí)點(diǎn)總結(jié),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有很大的幫助,需要的朋友可以參考下2021-04-04SpringBoot啟動(dòng)后啟動(dòng)內(nèi)嵌瀏覽器的方法
這篇文章主要介紹了SpringBoot啟動(dòng)后啟動(dòng)內(nèi)嵌瀏覽器的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12SpringCloud zuul 網(wǎng)關(guān)如何解決跨域問(wèn)題
這篇文章主要介紹了SpringCloud zuul網(wǎng)關(guān)解決跨域問(wèn)題的具體實(shí)現(xiàn)方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06Java Swing編寫一個(gè)簡(jiǎn)單的計(jì)算器軟件
大家好,本篇文章主要講的是Java Swing編寫一個(gè)簡(jiǎn)單的計(jì)算器軟件,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12計(jì)算機(jī)二級(jí)考試java軟件操作教程 教大家如何學(xué)習(xí)java
如何成為一名知識(shí)豐富的Java程序員,順利通過(guò)計(jì)算機(jī)二級(jí)Java考試,這篇文章主要主要教大家如何學(xué)習(xí)java,java的學(xué)習(xí)路線是什么,從何學(xué)起,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08