Mybatis延遲加載的實現(xiàn)示例
什么是延遲加載
延遲加載(Lazy Loading)是 MyBatis 的一種優(yōu)化機(jī)制,也稱為懶加載。它指的是在進(jìn)行關(guān)聯(lián)查詢時,按需加載數(shù)據(jù),而不是一次性加載所有關(guān)聯(lián)數(shù)據(jù),從而提高系統(tǒng)性能,減少不必要的數(shù)據(jù)庫查詢。
延遲加載配置
全局配置(SqlMapConfig.xml)
需要在 MyBatis 核心配置文件中開啟延遲加載開關(guān):
<settings>
<!-- 開啟延遲加載 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 將積極加載改為消極加載(按需加載) -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>lazyLoadingEnabled:全局開啟延遲加載開關(guān)(默認(rèn) false)aggressiveLazyLoading:是否開啟積極加載(默認(rèn) false)- 積極加載:加載一個對象時,會同時加載所有關(guān)聯(lián)對象
- 消極加載:只有真正使用關(guān)聯(lián)對象時才會加載
延遲加載實現(xiàn)(以 Account 和 User 為例)
1. 實體類定義
Account 類(包含 User 關(guān)聯(lián)對象):
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
// 關(guān)聯(lián)的用戶對象
private User user;
// getter/setter/toString省略
}User 類:
public class User implements Serializable {
private Integer id;
private String name;
private Date birthday;
private String sex;
private String address;
// getter/setter/toString省略
}2. Mapper 接口定義
AccountMapper 接口:
public interface AccountMapper {
// 查詢所有賬戶
List<Account> findAll();
}UserMapper 接口:
public interface UserMapper {
// 根據(jù)ID查詢用戶
User findById(Integer id);
}3. Mapper 映射文件配置(關(guān)鍵)
AccountMapper.xml 中配置延遲加載:
<mapper namespace="com.qcby.mapper.AccountMapper">
<!-- 延遲加載配置 -->
<select id="findAll" resultMap="accountMap">
select * from account
</select>
<resultMap id="accountMap" type="Account">
<id column="id" property="id"/>
<result column="uid" property="uid"/>
<result column="money" property="money"/>
<!-- 配置延遲加載 -->
<association
property="user" <!-- 關(guān)聯(lián)對象在Account中的屬性名 -->
javaType="User" <!-- 關(guān)聯(lián)對象的類型 -->
select="com.qcby.mapper.UserMapper.findById" <!-- 延遲加載時執(zhí)行的查詢 -->
column="uid"/> <!-- 傳遞給select查詢的參數(shù)(賬戶表中的uid字段) -->
</resultMap>
</mapper>UserMapper.xml 中需要有對應(yīng)的查詢方法:
<mapper namespace="com.qcby.mapper.UserMapper">
<select id="findById" parameterType="int" resultType="User">
select * from user where id = #{id}
</select>
</mapper>延遲加載測試代碼
public class Test02 {
private InputStream in;
private SqlSession session;
private AccountMapper mapper;
@Before
public void init() throws Exception {
// 加載配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
// 創(chuàng)建工廠對象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
// 創(chuàng)建session對象
session = factory.openSession();
// 獲取代理對象
mapper = session.getMapper(AccountMapper.class);
}
@After
public void destroy() throws Exception {
session.close();
in.close();
}
@Test
public void testLazyLoading() {
// 1. 查詢所有賬戶(此時只會執(zhí)行account表的查詢)
List<Account> accounts = mapper.findAll();
// 2. 遍歷賬戶列表
for (Account account : accounts) {
System.out.println("賬戶信息:" + account.getMoney());
// 3. 當(dāng)需要使用user屬性時,才會執(zhí)行user表的查詢(延遲加載觸發(fā)點)
System.out.println("用戶信息:" + account.getUser().getName());
}
}
}延遲加載執(zhí)行流程解析
- 執(zhí)行mapper.findAll()時,MyBatis 只查詢 account 表,獲取賬戶基本信息
- 此時 account 對象中的 user 屬性為代理對象(尚未查詢數(shù)據(jù)庫)
- 當(dāng)執(zhí)行account.getUser().getName()時,才會觸發(fā) User 查詢
- 執(zhí)行com.qcby.mapper.UserMapper.findById方法,傳入 uid 參數(shù)
- 獲取用戶信息并賦值給 account 的 user 屬性
延遲加載的優(yōu)點
- 減少不必要的 SQL 查詢,提高數(shù)據(jù)庫性能
- 減少內(nèi)存占用,只加載當(dāng)前需要的數(shù)據(jù)
- 適用于關(guān)聯(lián)數(shù)據(jù)較多但不一定都會使用的場景
注意事項
- 延遲加載只對關(guān)聯(lián)查詢有效(一對一、一對多等)
- 必須在核心配置文件中開啟延遲加載開關(guān)
- 如果提前關(guān)閉 SqlSession,會導(dǎo)致延遲加載失?。o法執(zhí)行后續(xù)查詢)
- 延遲加載通過 CGLIB 或 JDK 動態(tài)代理實現(xiàn),關(guān)聯(lián)對象是代理對象
到此這篇關(guān)于Mybatis延遲加載的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)Mybatis延遲加載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java擴(kuò)展Hibernate注解支持java8新時間類型
這篇文章主要介紹了java擴(kuò)展Hibernate注解支持java8新時間類型,需要的朋友可以參考下2014-04-04
jpa使用manyToOne(opntional=true)踩過的坑及解決
這篇文章主要介紹了jpa使用manyToOne(opntional=true)踩過的坑及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10
SpringBoot數(shù)據(jù)層測試事務(wù)回滾的實現(xiàn)流程
這篇文章主要介紹了SpringBoot數(shù)據(jù)層測試事務(wù)回滾的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-10-10
Spring注解驅(qū)動之關(guān)于@Bean注解指定初始化和銷毀的方法
這篇文章主要介紹了Spring注解驅(qū)動之關(guān)于@Bean注解指定初始化和銷毀的方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09
集群環(huán)境中使用ehcache_動力節(jié)點Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了集群環(huán)境中使用ehcache的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08

