【Mybatis架構】 延遲加載

 在上一篇博客中,咱們提到過有關於Mybatis輸出映射中resultMap可以實現延遲加載的事,然而真的是全部的resultMap都能實現延遲加載仍是咋地啊?如今咱們就來對那一句話作一下闡述和實例說明。html

 

1、首先咱們要知道什麼是延遲加載?

       延遲加載機制是爲了不一些無謂的性能開銷而提出來的,所謂延遲加載就是當在真正須要數據的時候,才真正執行數據加載操做;能夠簡單理解爲,只有在使用的時候,纔會發出sql語句進行查詢;延遲加載的有效期是在session打開的狀況下,當session關閉後,會報異常。當調用load方法加載對象時,返回代理對象,等到真正用到對象的內容時才發出sql語句。java

 

總結:須要查詢關聯信息時,使用mybatis延遲加載特性可有效的減小數據庫壓力,首次查詢只查詢主要信息,              關聯信息等用戶獲取時再加載。咱們已知的除了hibernate,還有咱們的Mybatis。mysql

 

2、實戰演練場:

(1)需求:還以咱們的上面兩篇文章的電商項目查詢訂單信息爲例,此次,咱們以訂單信息爲主要查詢表,而後關聯查詢對應的用戶信息。那什麼是延遲加載呢,就是咱們默認先只查詢訂單信息,當咱們須要客戶信息的時候呢,咱們再去關聯查詢用戶信息。這就是延遲加載了。spring

 

(2)pojo類的設計:sql

首先是訂單類:數據庫

 

[java]  view plain copy
 print?在CODE上查看代碼片派生到個人代碼片
  1. public class Orders {  
  2.     private Integer id;  
  3.     private Integer userId;  
  4.     private String number;  
  5.     private Date createtime;  
  6.     private String note;  
  7.     private User user;  
  8.     //getter、setter  
  9. }  
用戶信息類:

 

 

[java]  view plain copy
 print?在CODE上查看代碼片派生到個人代碼片
  1. public class User {  
  2.     private int id;  
  3.     private String username;  
  4.     private int sex;  
  5.     private Date birthday;  
  6.     private String address;  
  7.     //getter、setter  
  8. }  
再就是咱們Mapper映射文件離間對resultMap的定義:

 

 

[html]  view plain copy
 print?在CODE上查看代碼片派生到個人代碼片
  1. <pre code_snippet_id="2062392" snippet_file_name="blog_20161220_3_5346738" name="code" class="html"><resultMap type="com.ssm.mybatis.po.Orders" id="selectOrderUserLazyLoading">  
  2.         <!-- 配置映射的訂單信息 -->    
  3.         <id column="id" property="id"/>  
  4.         <result column="user_id" property="userId"/>  
  5.         <result column="number" property="number"/>  
  6.         <result column="createtime" property="createtime"/>  
  7.         <result column="note" property="note"/>  
  8.   
  9.         <!-- 配置映射的用戶信息 -->  
  10.         <association property="user" javaType="com.ssm.mybatis.po.User"   
  11.              select="com.ssm.mybatis.mapper.UserMapper.findUserById" column="user_id">             
  12.         </association>  
  13.     </resultMap></pre><br>  
  14. <br>  
  15. <pre></pre>  
  16. <p></p>  
  17. <pre></pre>  
  18. <p></p>  
  19. <pre></pre>  
  20. <pre></pre>  

在這裏,注意咱們的配置映射的映射信息裏面有一個select屬性,這裏實現的就是咱們的延遲加載,後面就是咱們定義的查詢用戶信息的Mapper的命名空間,也能夠說是一個指向。緩存

 

配置文件裏面statement對resultMap的調用配置:
[html]  view plain copy
 print?在CODE上查看代碼片派生到個人代碼片
  1. <select id="selectOrderUserLazyLoading" resultMap="OrderUserLazyLoadingResultMap" >  
  2.         select * from orders  
  3. </select>  

接下來,咱們定義一個mapper接口進行測試tomcat

 

[java]  view plain copy
 print?在CODE上查看代碼片派生到個人代碼片
  1. public interface OrdersMapper{  
  2.     List<Orders> findOrderUserLazyLoading() throws Exception;  
  3. }  
測試:

 

 

[java]  view plain copy
 print?在CODE上查看代碼片派生到個人代碼片
  1. @Test  
  2. public void selectOrderUserLazyLoading(){  
  3.     SqlSession session=sqlSessionFactory.openSession();  
  4.     OrdersMapperCustom ordersMapperCustomMapper=session.getMapper(OrdersMapperCustom.class);  
  5.     try {  
  6.         List<Orders> list=ordersMapperCustomMapper.findOrderUserLazyLoading();//查詢訂單信息  
  7.         if (list!=null) {//此處有斷點  
  8.                 System.out.println(list.get(0).getUser().getUsername());//查詢第一個訂單的用戶信息  
  9.         }  
  10.     } catch (Exception e) {//此處有斷電  
  11.         e.printStackTrace();  
  12.     }  
  13. }  
在上面的測試代碼裏面,咱們執行斷點查詢,分別在if和catch上打一個端點,看tomcat的日誌信息

 

你們能夠看到,當咱們執行到第一個斷點的時候,這裏mybatis只發出一條查詢訂單信息的sql去查詢全部的訂單信息。接下來,咱們繼續往下走:session

你們看到了,當咱們執行到想要獲取第一個訂單的用戶信息時,它又發出了另外一條根據id查詢用戶信息的sql,也就是說,當咱們須要調用用戶信息的查詢方法時,它纔會纔會去執行查詢,這也就是咱們所說的延遲加載,也叫作懶加載。你們能夠很明顯的看到,在這裏咱們使用的association來實現的延遲加載,其使用collection也同樣,至於使用association和collection有什麼區別呢,前面咱們也介紹過,association是將關聯信息映射到一個pojo對象中,而collection是將關聯消息映射到list結合中,就這麼簡單的理由mybatis

 

3、如何配置Mybatis延遲加載(懶加載)

      首先咱們要知道,Mybatis默認是不支持執行延遲加載(懶加載)的,這須要咱們手動去配置,去打開開關。而咱們能夠總結一下,但咱們須要設置開啓二級緩存的時候,咱們首先須要在Mybatis全局配置文件也就是咱們的sqlMapConfig.xml中去設置開啓二級緩存,而後再去每一個具體mapper映射文件中去確認本映射文件開啓二級緩存,也就是全部的全局性的功能或者是性能配置總閥門都在全局配置文件中的。因此咱們是否開啓延遲加載的這一項功能也是在sqlMapConfig.xml中進行配置:

 

[html]  view plain copy
 print?在CODE上查看代碼片派生到個人代碼片
  1. <settings>  
  2.    <setting name="lazyLoadingEnabled" value="true"/><!--延遲加載/懶加載-->  
  3.    <setting name="aggressiveLazyLoading" value="false"/><!--積極加載/預加載-->  
  4. </settings>  
而後如何在禁止懶加載的配置就不用再介紹了吧。

 

 

另外呢,經過看師哥師姐的博客以及外面人的介紹,mybatis的全局配置文件中的標籤是有前後順序的,按序分別是:properties、settings、typeAlliases、typeHandlers、objectFactory、plugins、environments、mappers。到底是爲何呢,爲了探究這個問題,我故意使用原生的mybatis(不與spring整合)配錯一個,結果然的如是個所說,報錯:

"元素類型爲configuration的內容必須匹配(properties?,settings?,typeAliases?,typeHandlers?……"

相關知識:http://www.cnblogs.com/selene/p/4607004.html

 

4、總結:

       以上,就是咱們mybatis實現延遲加載的一個簡單介紹,那如今回答剛開頭時問的問題,是全部的resultMap都能實驗延遲加載嗎?答案是:mybatis中能實現延時加載的是resultMap,彈死不是全部的resultMap都必須實現延時加載,咱們利用的是resultMap裏面的association和collection來實現的延遲加載。另外畢竟小編研究mybatis時間不長,不免有所疏漏,如有不足,還請各位指正,必及時修改。

相關文章
相關標籤/搜索