延遲載入又叫懶載入,也叫按需載入。也就是說先載入主信息,在需要的時候,再去載入從信息。
在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-tw/n/202358.html
微信掃一掃
支付寶掃一掃