程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> MyBatis學習--延遲加載,mybatis--延遲

MyBatis學習--延遲加載,mybatis--延遲

編輯:JAVA綜合教程

MyBatis學習--延遲加載,mybatis--延遲


  • 簡介

  在resultMap可以實現高級映射(使用association、collection實現一對一及一對多映射),association、collection具備延遲加載功能。例如:我們查詢訂單並且關聯查詢用戶信息。如果先查詢訂單信息即可滿足要求,當我們需要查詢用戶信息時再查詢用戶信息。把對用戶信息的按需去查詢就是延遲加載。

  延遲加載:先從單表查詢、需要時再從關聯表去關聯查詢,大大提高 數據庫性能,因為查詢單表要比關聯查詢多張表速度要快。

  • association實現延遲加載

  如果我們查詢訂單信息並且關聯查詢用戶信息,在不需要查看用戶信息的情況下只需要查詢訂單信息,如果需要查看用戶信息在查詢用戶信息。

  1、映射文件:

  需要定義兩個mapper的方法對應的statement,一個用於簡單的查詢,另一個用於需要查詢時再查詢。

  (1)、只查詢訂單信息

1 <select id="findOrderLazyLoad" resultMap="ordersUserResultMapLazyLoad">
2         select * from
3         orders
4 </select>

  (2)、關聯查詢用戶信息:

1 <select id="findUserLazyLoad" parameterType="int" resultType="user">
2         select * from user where id = #{value}
3 </select>

  上邊先去執行findOrderLazyLoad,當需要去查詢用戶的時候再去執行findUserLazyLoad,通過resultMap的定義將延遲加載執行配置起來。

 

 1 <!-- 訂單查詢關聯用戶的resultMap,將整個查詢結果映射到orders中,延遲加載 -->
 2     <resultMap type="com.luchao.mybatis.first.po.Orders" id="ordersUserResultMapLazyLoad">
 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         <!-- 實現對用戶信息進行延遲加載 select:指定延遲加載需要執行的statement的id(是根據user_id查詢用戶信息的statement) 
 9             要使用userMapper.xml中findUserById完成根據用戶id(user_id)用戶信息的查詢,如果findUserById不在本mapper中需要前邊加namespace 
10             column:訂單信息中關聯用戶信息查詢的列,是user_id 關聯查詢的sql理解為: SELECT orders.*, (SELECT username 
11             FROM USER WHERE orders.user_id = user.id)username, (SELECT sex FROM USER 
12             WHERE orders.user_id = user.id)sex FROM orders -->
13         <association property="user" javaType="com.luchao.mybatis.first.po.User"
14             select="findUserLazyLoad" column="user_id">
15 
16         </association>
17     </resultMap>

 

  select:指定延遲加載需要執行的statement的id(是根據user_id查詢用戶信息的statement),要使用userMapper.xml中findUserById完成根據用戶id(user_id)用戶信息的查詢,如果findUserById不在本mapper中需要前邊加namespace,column:訂單信息中關聯用戶信息查詢的列,是user_id。

  關聯查詢的SQL語句可以理解為:

 

1 SELECT orders.*,
2     (SELECT username FROM USER WHERE orders.user_id = user.id)username,
3     (SELECT sex FROM USER WHERE orders.user_id = user.id)sex
4 FROM orders

 

  2、Mapper接口:

1 //查詢訂單、訂單明細和用戶信息通過resultMap延遲加載
2 public List<Orders> findOrderLazyLoad() throws Exception;

  3、延遲加載的配置:

  mybatis默認沒有開啟延遲加載,需要在SqlMapConfig.xml中setting配置。在mybatis核心配置文件中配置:lazyLoadingEnabled、aggressiveLazyLoading

設置項

描述

允許值

默認值

lazyLoadingEnabled

全局性設置懶加載。如果設為‘false’,則所有相關聯的都會被初始化加載。

true | false

false

aggressiveLazyLoading

當設置為‘true’的時候,懶加載的對象可能被任何懶屬性全部加載。否則,每個屬性都按需加載。

true | false

true

  在SqlMapConfig.xml中配置

1 <settings>
2         <!-- 打開延遲加載的開關 -->
3         <setting name="lazyLoadingEnabled" value="true" />
4         <!-- 將積極加載改為消極加載即按需加載 -->
5         <setting name="aggressiveLazyLoading" value="false" />
6 </settings>

  4、測試:

 1 public void findOrderLazyLoad() throws Exception {
 2         // 獲取sqlSession對象
 3         SqlSession sqlSession = sqlSessionFactory.openSession();
 4         // 創建OrderMapper對象,MyBatis自動生成mapper代理
 5         OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
 6         // 調用orderMapper的方法,查詢訂單和用戶信息延遲加載
 7         List<Orders> Orders = orderMapper.findOrderLazyLoad();
 8         for (Orders order : Orders) {
 9             System.out.println(order.getUser());
10         }
11 }

  查詢結果:

 1 DEBUG [main] - ==>  Preparing: select * from orders 
 2 DEBUG [main] - ==> Parameters: 
 3 DEBUG [main] - <==      Total: 3
 4 DEBUG [main] - ==>  Preparing: select * from user where id = ? 
 5 DEBUG [main] - ==> Parameters: 1(Integer)
 6 DEBUG [main] - <==      Total: 1
 7 1-王五-2-null-null
 8 1-王五-2-null-null
 9 DEBUG [main] - ==>  Preparing: select * from user where id = ? 
10 DEBUG [main] - ==> Parameters: 10(Integer)
11 DEBUG [main] - <==      Total: 1
12 10-張明明3-1-北京市-Thu Jul 10 00:00:00 CST 2014

  可以看出先查詢orders表,然後在查看user的時候再查看user。

  • 延遲加載思考和總結

  如果不使用mybatis提供的association及collection中的延遲加載功能,如何實現延遲加載??

   實現方法如下:

  定義兩個mapper方法:1、查詢訂單列表,2、根據用戶id查詢用戶信息

  實現思路:

  先去查詢第一個mapper方法,獲取訂單信息列表

  在程序中(service),按需去調用第二個mapper方法去查詢用戶信息。

   總之:使用延遲加載方法,先去查詢簡單的sql(最好單表,也可以關聯查詢),再去按需要加載關聯查詢的其它信息。

  小結:  

  作用:當需要查詢關聯信息時再去數據庫查詢,默認不去關聯查詢,提高數據庫性能。只有使用resultMap支持延遲加載設置。

  場合:當只有部分記錄需要關聯查詢其它信息時,此時可按需延遲加載,需要關聯查詢時再向數據庫發出sql,以提高數據庫性能。

  當全部需要關聯查詢信息時,此時不用延遲加載,直接將關聯查詢信息全部返回即可,可使用resultType或resultMap完成映射。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved