延遲加載
1.什麼是延遲加載
resultMap能夠實現高級映射(使用association、collection實現一對一及一對多映射),association、collection具有延遲加載功能。
需求:
若是查詢訂單而且關聯查詢用戶信息。若是先查詢訂單信息便可知足要求,當咱們須要查詢用戶信息時再查詢用戶信息。把對用戶信息的按需去查詢就是延遲加載。
延遲加載:先從單表查詢、須要時再從關聯表去關聯查詢,大大提升數據庫性能,由於查詢單表要比關聯查詢多張錶速度要快。
2.使用association實現延遲加載
2.1需求
查詢訂單而且關聯查詢用戶信息
2.2mapper.xml
須要定義兩個mapper的方法對應的statement。
(1)只查詢訂單信息
SELECT * FROM ordersjava
<!-- 查詢訂單,關聯查詢用戶,用戶信息須要延遲加載 --> <select id="findOrdersUserLazyLoading" resultMap="OrdersUserLazyLoadingResultMap"> SELECT * FROM orders </select>
在查詢訂單的statement中使用association去延遲加載(執行)下邊的satatement(關聯查詢用戶信息)
(2)關聯查詢用戶信息
經過上邊查詢到的訂單信息中user_id去關聯查詢用戶信息
mysql
<!-- 延遲加載使用的sql --> <select id="findUserById" parameterType="int" resultType="cn.edu.hpu.mybatis.PO.User"> SELECT * FROM USER WHERE id=#{id} </select>
上邊先去執行findOrdersUserLazyLoading,當須要去查詢用戶的時候再去執行findUserById,經過resultMap的定義將延遲加載執行配置起來。
2.3延遲加載resultMap
使用association中的select指定延遲加載去執行的statement的id。sql
<!-- 延遲加載的resultMap --> <resultMap id="OrdersUserLazyLoadingResultMap" type="cn.edu.hpu.mybatis.PO.Orders"> <!-- 對訂單信息進行映射配置 --> <id column="id" property="id"/> <result column="user_id" property="userId"/> <result column="number" property="number"/> <result column="creattime" property="creattime"/> <result column="note" property="note"/> <!-- 實現延遲加載用戶信息 select:指定延遲加載所須要執行的sql語句,也就是Mapper.xml配置文件中的某個SELECT標籤對 column:訂單信息中關聯用戶信息查詢的列,是user_id。 關聯的sql理解爲: SELECT orders.*, (SELECT username FROM USER WHERE orders.user_id=user.id)username, (SELECT sex FROM USER WHERE orders.user_id=user.id)sex FROM orders;--> <association property="user" javaType="cn.edu.hpu.mybatis.PO.User" select="findUserById" column="user_id"> </association> </resultMap>
2.4mapper.java數據庫
package cn.edu.hpu.mybatis.mapper; import java.util.List; import cn.edu.hpu.mybatis.PO.Orders; import cn.edu.hpu.mybatis.PO.OrdersCustom; import cn.edu.hpu.mybatis.PO.User; //訂單mapper public interface OrdersCustomMapper { //... //查詢訂單關聯查詢用戶,其中用戶信息延遲加載 public List<Orders> findOrdersUserLazyLoading() throws Exception; }
2.5測試
2.5.1測試思路:
一、執行上邊mapper方法(findOrdersUserLazyLoading),內部去調用 cn.itcast.mybatis.mapper.OrdersMapperCustom中的findOrdersUserLazyLoading只查 詢orders信息(單表)。
二、在程序中去遍歷上一步驟查詢出的List<Orders>,當咱們調用Orders中的getUser方法時,開始進行延遲加載。
三、延遲加載,去調用UserMapper.xml中findUserbyId這個方法獲取用戶信息。
2.5.2延遲加載配置
mybatis默認沒有開啓延遲加載,須要在SqlMapConfig.xml中setting配置。
在mybatis核心配置文件中配置:
lazyLoadingEnabled、aggressiveLazyLoading
設置項 描述 容許值 默認值
lazyLoadingEnabled 全局性設置懶加載。若是設爲‘false’,則全部相關聯的都會被初始化加載。true | falsefalse
aggressiveLazyLoading 當設置爲‘true’的時候,懶加載的對象可能被任何懶屬性所有加載。不然,每一個屬性都按需加載。true | falsetrue
在SqlMapConfig.xml中配置:mybatis
<configuration> ...... <!-- settings--> <settings> <!-- 打開延遲加載的開關 --> <setting name="lazyLoadingEnable" value="true"/> <!-- 將積極加載改成消極加載(及按需加載) --> <setting name="aggressiveLazyLoading" value="false"/> </settings> ...... </configuration>
2.5.3測試代碼
//查詢訂單關聯用戶信息,用戶信息實現延遲加載
app
@Test public void testFindOrderUserLazyLoading() throws Exception{ SqlSession sqlSession=sqlSessionFactory.openSession(); //建立代理對象 OrdersCustomMapper ordersMapperCustom=sqlSession.getMapper(OrdersCustomMapper.class); //調用mapper的方法 List<Orders> ods=ordersMapperCustom.findOrdersUserLazyLoading(); for (int i = 0; i < ods.size(); i++) { Orders od=ods.get(i); //執行getUser去查詢用戶信息,這裏實現了延遲加載 User user=od.getUser(); System.out.println("用戶姓名:"+user.getUsername()); } }
輸出結果及日誌信息:性能
DEBUG [main] - Opening JDBC Connection DEBUG [main] - Created connection 29706134. DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.Connection@1c54796] DEBUG [main] - ==> Preparing: SELECT * FROM orders DEBUG [main] - ==> Parameters: DEBUG [main] - <== Total: 3 DEBUG [main] - ==> Preparing: SELECT * FROM USER WHERE id=? DEBUG [main] - ==> Parameters: 1(Integer) DEBUG [main] - <== Total: 1 用戶姓名:張三 用戶姓名:張三 DEBUG [main] - ==> Preparing: SELECT * FROM USER WHERE id=? DEBUG [main] - ==> Parameters: 3(Integer) DEBUG [main] - <== Total: 1 用戶姓名:劉莉莉
2.6延遲加載思考
不使用mybatis提供的association及collection中的延遲加載功能,如何實現延遲加載??
實現方法以下:
定義兩個mapper方法:
一、查詢訂單列表
二、根據用戶id查詢用戶信息
實現思路:
先去查詢第一個mapper方法,獲取訂單信息列表
在程序中(service),按需去調用第二個mapper方法去查詢用戶信息。
總之:
測試
使用延遲加載方法,先去查詢簡單的sql(最好單表,也能夠關聯查詢),再去按須要加載關聯查詢的其它信息。spa