Java後端--32--Mybatis的多級快取和懶載入
一、一級快取
快取:程式經常要呼叫的物件存在記憶體中,方便其使用時可以快速呼叫,不必去資料庫或者其他持久化裝置中查詢,主要就是提高效能。
Mybatis一級快取:一級快取的作用域是SqlSession,同一個SqlSession中執行相同的SQL查詢時(相同的SQL和引數),第一次會去查詢資料庫並寫在快取中,第二次會直接從快取中取。一級快取是基於PerpetualCache的HashMap本地快取,另外,一級快取是預設開啟的。
失效策略:當執行兩次SQL的查詢中間發生了增刪改的操作,即insert、update、delete等操作commit後會清空該SqlSession快取,比如SqlSession關閉或者清空等。
程式碼示例:
SqlSessionDemo.java
// 查詢musicId為3的資料
// for迴圈兩次,第二次的時候會觸發一級快取
for(int i=0; i<2; i++) {
Music music = musicMapper.selectById(3);
System.out.println(music.toString());
}
二、Mybatis二級快取
簡介:二級快取是NameSpace級別的,多個SqlSession去操作同一個NameSpace下Mapper的sql語句,多個SqlSession可以共用二級快取,如果兩個mapper的NameSpace相同,(即使是兩個mapper,那麼這兩個mapper中執行sql查詢到的資料也將存在相同的二級快取區域中,但是最後是每個Mapper單獨的名稱空間)。二級快取是基於PerpetualCache的HashMap本地快取,可自定義儲存源,如 Ehcache/Redis等。另外,二級快取預設是沒有開啟的。
操作流程:第一次呼叫某個NameSpace下的SQL去查詢資訊,查詢到的資訊會存放該mapper對應的二級快取區域。 第二次呼叫同個NameSpace下的mapper對映檔案中,相同的sql去查詢資訊,會去對應的二級快取內取結果。
失效策略:執行同個NameSpace下的mapepr對映檔案中增刪改sql,並執行了commit操作,會清空該二級快取。
注意:實現二級快取的時候,MyBatis建議返回的POJO是可序列化的, 也就是建議實現Serializable介面。
快取淘汰策略:會使用預設的LRU演算法來收回(最近最少使用的被淘汰)。
程式碼示例:
1、domain/Music.java
// 音樂類
// 這裡使用了Serializable介面,主要是為了實現二級快取
public class Music implements Serializable {
......
}
2、domian/MusicOrder.java
// 這裡使用了Serializable介面,主要是為了實現二級快取
public class MusicOrder implements Serializable {
......
}
3、resources/config/mybatis-config.xml
<!-- settings設定必須加在environments上面 -->
<settings>
<!-- 下劃線自動對映駝峰欄位,預設是false -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 這個配置使全域性的對映器(二級快取)啟用或禁用快取,全域性總開關,這裡關閉後mapper中開啟了也沒用 -->
<setting name="cacheEnabled" value="true" />
</settings>
4、resources/mapper/MusicMapper.xml
<!-- 開啟mapper的NameSpace下的二級快取 -->
<!--
eviction:代表的是快取回收策略,常見下面兩種。
1、LRU:最近最少使用的淘汰,一處最長時間不用的物件
2、FIFO:先進先出淘汰,按物件進入快取的順序來移除他們
flushInterval::重新整理間隔時間,單位為毫秒,這裡配置的是100秒重新整理,如果不配置它,當SQL被執行的時候才會去重新整理快取。
size:引用數目,代表快取最多可以儲存多少個物件,設定過大會導致記憶體溢位
readOnly:只讀,快取資料只能讀取而不能修改,預設值是false
-->
<cache eviction="LRU" flushInterval="100000" readOnly="true" size="1024"/>
5、SqlSessionCacheDemo.java
public class SqlSessionCacheDemo {
public static void main(String [] args) throws IOException {
String resouce = "config/mybatis-config.xml";
//讀取配置檔案
InputStream inputStream = Resources.getResourceAsStream(resouce);
//構建Session工廠
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//獲取Session
try{
// 開啟第一個SqlSession
SqlSession sqlSession1 = sqlSessionFactory.openSession();
MusicMapper MusicMapper1 = sqlSession1.getMapper(MusicMapper.class);
// 查詢musicID為3的資料
Music music1 = MusicMapper1.selectById(3);
System.out.println(music1.toString());
// 提交快取
sqlSession1.commit();
// 開啟第二個SqlSession
SqlSession sqlSession2 = sqlSessionFactory.openSession();
MusicMapper musicMapper2 = sqlSession1.getMapper(MusicMapper.class);
// 查詢musicID為3的資料
Music music2 = musicMapper2.selectById(3);
System.out.println(music2.toString());
// 提交快取
sqlSession2.commit();
}catch (Exception e){
e.printStackTrace();
}
}
}
6、執行效果演示
可見查詢了兩次資料,但只執行了一次SQL語句,二級快取生效
三、懶載入
懶載入:按需載入,先從單表查詢,需要時再從關聯表去關聯查詢,能大大提高資料庫效能,但並不是所有場景下使用懶載入都能提高效率。
Mybatis懶載入:resultMap裡面的association、collection有延遲載入功能(延遲載入也就是懶載入)。
程式碼示例:
1、resources/mapper/MusicOrderMapper.xml
<!-- 懶載入 -->
<resultMap id="MusicOrderResultMapLazy" type="MusicOrder">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="out_trade_no" property="outTradeNo"/>
<result column="create_time" property="createTime"/>
<result column="state" property="state"/>
<result column="total_fee" property="totalFee"/>
<result column="music_id" property="musicId"/>
<result column="music_title" property="musicTitle"/>
<result column="music_img" property="musicImg"/>
<!--
select:指定延遲載入需要執行的statement id
column:和select查詢關聯的欄位
-->
<association property="user" javaType="User" column="user_id" select="findUserByUserId"/>
</resultMap>
<!-- 一對一管理查詢訂單,訂單內部包含使用者屬性。懶載入 -->
<select id="queryMusicOrderListLazy" resultMap="MusicOrderResultMapLazy">
select
o.id id,
o.user_id ,
o.out_trade_no,
o.create_time,
o.state,
o.total_fee,
o.music_id,
o.music_title,
o.music_img
from music_order o
</select>
<!-- 查詢使用者資訊 -->
<select id="findUserByUserId" resultType="User">
select * from user where id=#{id}
</select>
2、resources/config/mybatis-config.xml
<!-- settings設定必須加在environments上面 -->
<settings>
<!-- 下劃線自動對映駝峰欄位,預設是false -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 這個配置使全域性的對映器(二級快取)啟用或禁用快取,全域性總開關,這裡關閉後mapper中開啟了也沒用 -->
<setting name="cacheEnabled" value="true" />
<!-- 延遲載入總開關 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 將aggressiveLazyLoading設定為false表示按需載入,預設為true -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
3、dao/MusicOrderMapper.java
// 查詢全部訂單,關聯使用者資訊,懶載入
List<MusicOrder> queryMusicOrderListLazy();
4、SqlSessionDemo.java
// resultmap association關聯查詢(測試懶載入)
MusicOrderMapper musicOrderMapper = sqlSession.getMapper(MusicOrderMapper.class);
List<MusicOrder> musicOrderList = musicOrderMapper.queryMusicOrderListLazy();
System.out.println(musicOrderList.size());
for(MusicOrder musicOrder : musicOrderList){
System.out.println(musicOrder.getMusicTitle());
System.out.println(musicOrder.getUser().getName());
}
5、執行演示,可見懶載入生效
四、總結
總結一下本節的程式碼結構:
相關文章
- Hibernate 基本操作、懶載入以及快取快取
- 多層巢狀後的 Fragment 懶載入實現巢狀Fragment
- JAVA快取-Redis入門級使用Java快取Redis
- 懶載入和預載入
- Java中的多級快取設計與實現Java快取
- mybatis延遲載入和快取MyBatis快取
- 圖片預載入和懶載入
- Mybatis的快取——一級快取和原始碼分析MyBatis快取原始碼
- k05_多級快取快取
- 多級快取架構(六)快取架構
- 懶載入
- Vue 的懶載入Vue
- mybatis基礎系列(四)——關聯查詢、延遲載入、一級快取與二級快取MyBatis快取
- 預載入與快取快取
- 懶載入– 端對端分享功能 –微信釘釘
- 1道面試題---懶載入和預載入面試題
- Ribbon - 懶載入
- mybatis原始碼學習:一級快取和二級快取分析MyBatis原始碼快取
- Mybatis延遲載入、快取MyBatis快取
- element 級聯選擇器懶載入回顯
- el-select資料過多懶載入(loadmore)
- MyBatis快取機制(一級快取,二級快取)MyBatis快取
- 億級流量客戶端快取之Http快取與本地快取對比客戶端快取HTTP
- OpenResty+lua+redis+mysql多級快取RESTRedisMySql快取
- 小說APP原始碼的圖片載入方式,懶載入和預載入的實現APP原始碼
- dva中元件的懶載入元件
- Mybatis一級快取和結合Spring Framework後失效的原始碼探究MyBatis快取SpringFramework原始碼
- Mybatis的二級快取、使用Redis做二級快取MyBatis快取Redis
- 【譯】懶載入元件元件
- 圖片懶載入
- vue路由懶載入Vue路由
- Vue元件懶載入Vue元件
- Hibernate 之 懶載入
- mybatis快取-二級快取MyBatis快取
- Laravel 實現二級快取 提高快取的命中率和細粒化快取 keyLaravel快取
- Mybatis 一級快取和二級快取原理區別 (圖文詳解)MyBatis快取
- Vue 路由按需載入(路由懶載入)Vue路由
- 開源框架——圖片載入和快取方案總結框架快取