Mybatis延遲載入中有兩個標籤支援延遲載入
1 延遲載入
延遲載入也叫做懶載入lazy
按需要進行載入,是優化查詢速度的方法
Mybatis中有兩個標籤支援延遲載入
<association>
<collection>
操作步驟:
1. 開啟延遲載入開關,關閉積極載入開關
核心配置檔案sqlMapconfig.xml
<settings> <!-- 開啟延遲載入開關 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 關閉積極載入開關 --> <setting name="aggressiveLazyLoading" value </settings> |
2. 編寫程式碼
對映檔案:
<resultMap type="cn.itcast.po.Orders" id="orderAndUserLazyResultMap"> <id column="id" property="id"/> <result column="user_id" property="userId"/> <result column="number" property="number"/> <result column="createtime" property="createtime" <result column="note" property="note"/> <!-- 使用延遲載入 select:呼叫要執行的sql語句,使用那個sql的namespace+.+sql語句的id 例如:cn.itcast.mapper.UserMapper.findUserById column:是orders表中與user表關聯的欄位 --> <association property="user" javaType="cn.itcast.po.User" select="cn.itcast.mapper.UserMapper.findUserById" column </association> </resultMap> <select id="findOrderAndUserLazy" resultMap="orderAndUserLazyResultMap"> select * from orders </select> |
介面:
public List<Orders> findOrderAndUserLazy(); |
測試程式碼:
@Test publicvoid testFindOrderAndUserLazy() throws Exception{ SqlSession openSession = sqlSessionFactory.openSession(); OrdersMapper ordersMapper = openSession.getMapper(OrdersMapper.class); List<Orders> list = ordersMapper.findOrderAndUserLazy(); for(Orders order : list){ String number = order.getNumber(); System.out.println(number); User user = order.getUser(); System.out.println(user.getUsername()); } } |
2 總結
1. 對單個物件的對映關係使用:<association
2. 對集合物件的對映關係使用:<collection
3. 延遲載入:需要在核心配置檔案中配置開關;在mybatis中association和collection支援延遲載入
3 快取
優化查詢速度
3.1 一級快取
是SqlSession級別的,一級快取由mybatis自己控制,不需要人為干預
1. 第一次查詢會查詢一級快取,如果快取中沒有資料會從資料庫中查詢
2. 如果有更新、刪除、修改操作,那麼會清空快取
3. 接著再次執行查詢則會去資料庫中查詢資料並放到快取中
4. 再次查詢則直接從快取中查詢資料
對映檔案:
<select id="findUserByIdCache1" parameterType="int" resultType="user"> select * from User where id=#{aaa} </select> |
介面:
public User findUserByIdCache1(Integer id); |
測試程式碼:
@Test publicvoid testFindUserByIdCache1() throws Exception{ SqlSession openSession = sqlSessionFactory.openSession(); //獲得Mapper物件 UserMapper userMapper = openSession.getMapper(UserMapper.class); //第一次查詢 User user1 = userMapper.findUserByIdCache1(1); System.out.println(user1); user1.setUsername("李四"); userMapper.updateUserById(user1); openSession.commit(); //第二次查詢 User user2 = userMapper.findUserByIdCache1(1); System.out.println(user2); } |
3.2 二級快取
二級快取中的資料可以儲存在記憶體中,或者硬碟中。
操作步驟:
1. 開啟二級快取
在SqlMapConfig.xml中加入
<!-- 開啟二級快取 --> <setting name="cacheEnabled" value="true"/> |
2. 在需要二級快取的對映檔案中加入<cache />
在UserMapper.xml中加入
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace:名稱空間,作用為Sql隔離 --> <mapper namespace="cn.itcast.mapper.UserMapper"> <!-- 使用二級快取 --> <cache /> |
3. 將查詢的POJO實現Serializable介面
publicclass User implementsSerializable{ privatestaticfinallongserialVersionUID = -6538886943664906447L; privateintid; private String username;// 使用者姓名 private String sex;// 性別 private Date birthday;// 生日 private String address;// 地址 |
對映檔案:
<select id="findUserByIdCache2" parameterType="int" resultType="user"> select * from User where id=#{aaa} </select> |
介面:
public User findUserByIdCache2(Integer id); |
測試程式碼:
@Test publicvoid testFindUserByIdCache2() throws Exception{ SqlSession openSession = sqlSessionFactory.openSession(); //獲得Mapper物件 UserMapper userMapper = openSession.getMapper(UserMapper.class); //第一次查詢 User user = userMapper.findUserByIdCache2(1); System.out.println(user); openSession.close(); //第二次查詢 openSession = sqlSessionFactory.openSession(); userMapper = openSession.getMapper(UserMapper.class); User user1 = userMapper.findUserByIdCache2(1); System.out.println(user1); } |
測試程式碼:
@Test publicvoid testFindUserByIdCache2() throws Exception{ SqlSession openSession = sqlSessionFactory.openSession(); //獲得Mapper物件 UserMapper userMapper = openSession.getMapper(UserMapper.class); //第一次查詢 User user = userMapper.findUserByIdCache2(1); System.out.println(user); openSession.close(); //執行更新操作 openSession = sqlSessionFactory.openSession(); userMapper = openSession.getMapper(UserMapper.class); user.setUsername("王六"); userMapper.updateUserById(user); openSession.commit(); openSession.close(); //第二次查詢 openSession = sqlSessionFactory.openSession(); userMapper = openSession.getMapper(UserMapper.class); User user1 = userMapper.findUserByIdCache2(1); System.out.println(user1); openSession.close(); //第三次查詢 openSession = sqlSessionFactory.openSession(); userMapper = openSession.getMapper(UserMapper.class); User user2 = userMapper.findUserByIdCache2(1); System.out.println(user2); openSession.close(); } |
3.3 分散式快取
1. 匯入jar包
2. 新增ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"> <diskStore path="E:\" /> <!-- maxElementsInMemory記憶體中快取的最大個數 --> <!-- maxElementsOnDisk硬碟上快取的最大個數 --> <!-- eternal設定快取中的資料是否永遠不過期 --> <!-- overflowToDisk設定快取中的資料是否永遠不過期 --> <!-- overflowToDisk快取資料閒置時間,超過則刪除資料--> <!-- timeToIdleSeconds快取資料閒置時間,超過則刪除資料--> <!-- timeToLiveSeconds快取資料存活時間,超過則刪除資料 --> <!-- diskExpiryThreadIntervalSeconds磁碟快取清理執行緒執行間隔--> <!-- memoryStoreEvictionPolicy快取策略,最近最少使用,當快取大小到達極限時刪除最近很少使用的--> <defaultCache maxElementsInMemory="1000" maxElementsOnDisk="10000000" eternal="false" overflowToDisk="false" timeToIdleSeconds="120" timeToLiveSeconds="120" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> </defaultCache> </ehcache> |
3. 配置對映檔案中使用ehcache實現
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/> |
4. 測試(同二級快取測試)
flushCache重新整理快取:不配置預設為true
如果配置成false就是永遠不重新整理快取,也就意味著快取中的資料如果更新或者刪除還有新增的時候,就成了髒資料了。
useCache是否使用快取:如果不配置預設為true使用快取。
如果遇到重新整理,更改,刪除操作頻繁的情況下可以設定成false,不適用快取,因為快取的清空還有填充資料,也是需要耗費資源的
3.4 快取的使用:
增加、修改、刪除這樣的操作很少的情況下才能使用快取。
比如電話局的話務系統,話單的查詢功能可以使用快取。