延遲加載又叫懶加載,也叫按需加載。也就是說先加載主信息,在需要的時候,再去加載從信息。
在mybatis中,resultMap標籤 的association標籤和collection標籤具有延遲加載的功能。
1、拷貝jar包
延遲加載中查詢出來的是一個代理對象,不是真正的對象本身,可參考hibernate中的load方法,利用log4j將日誌信息打印在控制台可以很明確的看到,所以在使用延遲加載時,需要用到cglib包。
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.6</version> </dependency>
2、配置全局設置
<!– 全局設置 –>
<settings>
<!-- 打開延遲加載的開關,默認為false,即非延遲加載 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 將積極加載改為消極加載 --> <setting name="aggressiveLazyLoading" value="true"/> <!--兩個合在一起配置就是,消極的延遲加載-->
</settings>
官方對這兩個屬性的解釋是:
lazyLoadingEnabled 全局啟用或禁用延遲加載。當禁用時,所有關聯對象都會即時加載。(是否延遲加載當前對象的關聯對象)
aggressiveLazyLoading 當啟用時,有延遲加載屬性的對象在被調用時將會完全加載任意屬性。否則,每種屬性將會按需要加載。(是否延遲加載當前對象屬性的關聯對象)
延遲加載會生成代理對象
3、測試
/**
* 測試延遲加載
*/
@Test
public void testLazyLoading(){
SqlSession session = MyBatisUtil.getSqlSession();
BlogMapper blogImpl = session.getMapper(BlogMapper.class);
Blog blog = blogImpl.selectById(1);
session.close();
//默認是積極加載的,需要在Config配置文件的全局中配置
System.out.println(blog.getId());
//System.out.println(blog.getAuthor());
}
根據MyBatis官方文檔中給出的案例,Blog類中關聯了Author,此次測試,基於官方文檔中的案例
(1)什麼都不配置,且只打印blog的id

可以看出,當什麼都不配置時,默認為用一個從連接池中取得的連接完成兩個sql語句的查詢,即非延遲,積極的查詢
(2)配置 <setting name=”lazyLoadingEnabled” value=”true” />
aggressiveLazyLoading的默認值為false 即只配 lazyLoadingEnabled為true或者同時配置 兩個為一true一false的結果相同
只要結果映射中配置了association
則執行懶加載特性:不查詢author的屬性,則不執行子查詢。
當只有測試中的第一條輸出語句執行時結果如下圖:

可以看到此時是懶加載。
當測試中的兩條輸出語句都執行時結果如下圖:

可以看出,此時為非積極的延遲加載,只有在需要查詢author時才會執行查詢author的sql語句。
(2)配置 <setting name=”lazyLoadingEnabled” value=”true” />且
<setting name="aggressiveLazyLoading" value="true"/> 此時為積極的延遲加載
當只有測試中的第一條輸出語句執行時結果如下圖:

可以看出,此時的結果為雖然只需要blog的id,但是author依舊被查詢,而且用到的是兩個連接查詢。
當測試中的兩條輸出語句都執行時結果如下圖:

可以看到,此時兩個輸出語句打印的結果是連接在一塊的,也就是說在打印author信息之前,author已經被查詢出來,而不是像上面非積極的延遲加載那樣,用到author時才執行sql語句。
如果第一個設置的不是true時,第二個設置是沒有意義的,這個可以看一下官方文檔上寫的,看完官方文檔就一目了然了

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/202358.html
微信掃一掃
支付寶掃一掃