05、MyBatis 緩存

来源:https://www.cnblogs.com/CSAH/archive/2020/06/23/13152304.html
-Advertisement-
Play Games

1.MyBatis緩存 MyBatis 包含一個非常強大的查詢緩存特性,它可以非常方便地配置和定製.緩存可以極大的提升查詢效率. 1).一級緩存 public Employee getEmpById(Integer id); <select id="getEmpById" resultType="c ...


1.MyBatis緩存

  MyBatis 包含一個非常強大的查詢緩存特性,它可以非常方便地配置和定製.緩存可以極大的提升查詢效率.

 

1).一級緩存

	public Employee getEmpById(Integer id);

  

	<select id="getEmpById" resultType="com.atguigu.mybatis.bean.Employee" databaseId="mysql" >
		select * from tbl_employee where id = #{id}
	</select>

  

	@Test
	public void testFirstLevelCache() throws IOException {
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
		SqlSession openSession = sqlSessionFactory.openSession();
		try {
			
			EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
			Employee emp01 = mapper.getEmpById(10);
			System.out.println(emp01);
			
			//
			Employee emp02 = mapper.getEmpById(1-0);
			System.out.println(emp02);
			System.out.println(emp01==emp02);
			
		}finally {
			openSession.close();
		}
	}

2).一級緩存失效情況

(1).sqlSession不同

(2).sqlSession相同,查詢條件不同(當前一級緩存中還沒有這個數據)

(3).sqlSession相同,兩次查詢之間執行了增刪改操作(這次增刪改可能對當前數據有影響)

(4).sqlSession相同,手動清除了一級緩存

	public Employee getEmpById(Integer id);

  

	<select id="getEmpById" resultType="com.atguigu.mybatis.bean.Employee" databaseId="mysql" >
		select * from tbl_employee where id = #{id}
	</select>

  

	@Test
	public void testFirstLevelCache() throws IOException {
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
		SqlSession openSession = sqlSessionFactory.openSession();
		try {
			
			EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
			Employee emp01 = mapper.getEmpById(10);
			System.out.println(emp01);
			
			//1、Sqlsession不同
//			SqlSession openSession2 = sqlSessionFactory.openSession();
//			EmployeeMapper mapper2 = openSession2.getMapper(EmployeeMapper.class);
//			Employee emp02 = mapper2.getEmpById(10);
			
			//2、sqlSession相同,查詢條件不同
//			Employee emp02 = mapper.getEmpById(3);
//			System.out.println(emp02);
//			System.out.println(emp01==emp02);
			
			//3、sqlSession相同,兩次查詢之間執行了增刪改操作
//			mapper.addEmp(new Employee(null, "testCache", "[email protected]", "1"));
//			System.out.println("數據添加成功");
//			Employee emp02 = mapper.getEmpById(10);
//			System.out.println(emp02);
//			System.out.println(emp01==emp02);
			
			//4、sqlSession相同,手動清除了一級緩存
			openSession.clearCache();
			Employee emp02 = mapper.getEmpById(10);
			System.out.println(emp02);
			System.out.println(emp01==emp02);
			
		}finally {
			openSession.close();
		}
	}

  

3).二級緩存

  二級緩存(second level cache),全局作用域緩存.

  二級緩存預設不開啟,需要手動配置.

  MyBatis提供二級緩存的介面以及實現,緩存實現要求POJO實現Serializable介面.

  二級緩存在 SqlSession 關閉或提交之後才會生效.

(1).二級緩存使用

二級緩存使用:

①.開啟全局二級緩存配置:<setting name="cacheEnabled" value="true"/>

②.去需要使用二級緩存的xml中配置使用二級緩存;添加<cache></cache>

③.POJO需要實現序列化介面

		<setting name="cacheEnabled" value="true"/>

  

<mapper namespace="com.atguigu.mybatis.dao.EmployeeMapper">
	<!-- cache:使用二級緩存的namespace -->
	<!-- eviction:緩存的清除策略;LRU|FIFO|SOFT|WEAK -->
		<!-- LRU – 最近最少使用的:移除最長時間不被使用的對象。 -->
		<!-- FIFO – 先進先出:按對象進入緩存的順序來移除它們。 -->
		<!-- SOFT – 軟引用:基於垃圾回收器狀態和軟引用規則移除對象。 -->
		<!-- WEAK – 弱引用:更積極地基於垃圾收集器狀態和弱引用規則移除對象。 -->
	<!-- flushInterval(刷新間隔):緩存多長時間清空一次,預設不清空,可以設置一個毫秒值啟用刷新間隔 -->
	<!-- readOnly(只讀):屬性可以被設置為 true 或 false -->
		<!-- true:只讀;mybatis認為所有從緩存中獲取數據的操作都是只讀操作,不會修改數據; -->
			<!-- 只讀的緩存會給所有調用者返回緩存對象的相同實例。 因此這些對象不能被修改。 提供了可觀的性能提升-->
		<!-- false:非只讀;mybatis覺得獲取的數據可能會被修改; -->
			<!-- 可讀寫的緩存會(通過序列化)返回緩存對象的拷貝。 速度上會慢一些,但是更安全,因此預設值是 false -->
	<!-- size(引用數目):屬性可以被設置為任意正整數,要註意欲緩存對象的大小和運行環境中可用的記憶體資源.預設值是 1024 -->
	<!-- type:屬性指定的類必須實現 org.apache.ibatis.cache.Cache 介面.且提供一個接受 String 參數作為 id 的構造器 -->
		<!-- 指定自定義緩存的全類名,實現Cache介面即可 -->
	<!-- <cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024"></cache> -->
	<cache></cache>
</mapper>

  

	@Test
	public void testSecondLevelCache() throws IOException {
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
		SqlSession openSession = sqlSessionFactory.openSession();
		SqlSession openSession2 = sqlSessionFactory.openSession();
		try {
			//1、
			EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
			EmployeeMapper mapper2 = openSession2.getMapper(EmployeeMapper.class);
			
			Employee emp01 = mapper.getEmpById(1);
			System.out.println(emp01);
			openSession.close();
			
			//第二次查詢是從二級緩存中拿到的數據,並沒有發送新的sql
			//mapper2.addEmp(new Employee(null, "aaa", "nnn", "0"));
			Employee emp02 = mapper2.getEmpById(1);
			System.out.println(emp02);
			openSession2.close();
		}finally {
			
		}
	}

  

(2).二級緩存工作原理

二級緩存工作原理:

①.一個會話,查詢一條數,這個數據就會被放在當前會話的一級緩存中;

②.如果會話關閉;一級緩存中的數據會被保存到二級緩存中;新的會話查詢信息,就可以參照二級緩存中的內容;

③.不同namespace查出的數據會放在自己對應的緩存中(map):sqlSession===EmployeeMapper==>Employee|DepartmentMapper===>Department

④.二級緩存工作效果:查出的數據都會被預設先放在一級緩存中.只有會話提交或者關閉以後,一級緩存中的數據才會轉移到二級緩存中;

 

(3).二級緩存屬性設置

①.cacheEnabled="true|false": false關閉緩存(二級緩存關閉)(一級緩存一直可用的)

②.每個select標簽都有useCache="true|false": false不使用緩存(一級緩存依然使用,二級緩存不使用)

③.*每個增刪改標簽的:flushCache="true|false":(一級二級都會清除)增刪改執行完成後就會清楚緩存;

測試:flushCache="true":一級緩存會被清空;二級也會被清空;每次查詢之後都會清空緩存,緩存是沒有被使用的;

④.sqlSession.clearCache();只是清除當前session的一級緩存

⑤.localCacheScope:本地緩存作用域;一級緩存SESSION;當前會話的所有數據保存在會話緩存中;STATEMENT:可以禁用一級緩存;

/**

* MyBatis系統中預設定義了兩級緩存:一級緩存和二級緩存

* 一級緩存(本地緩存):sqlSession級別的緩存;一級緩存是一直開啟的;SqlSession級別的一個Map

* 與資料庫同一次會話期間查詢到的數據會放在本地緩存中;

* 以後如果需要獲取相同的數據,直接從緩存中拿,沒必要再去查詢資料庫;

* 一級緩存失效情況:沒有使用到一級緩存的情況,效果就是兩次查詢都需要向資料庫發出查詢

* 1sqlSession不同

* 2sqlSession相同,查詢條件不同(當前一級緩存中還沒有這個數據)

* 3sqlSession相同,兩次查詢之間執行了增刪改操作(這次增刪改可能對當前數據有影響)

* 4sqlSession相同,手動清除了一級緩存

*

* 二級緩存(全局緩存):基於namespace級別的緩存;一個namespace對應一個二級緩存;

* 二級緩存工作原理:

* 1、一個會話,查詢一條數,這個數據就會被放在當前會話的一級緩存中;

* 2、如果會話關閉;一級緩存中的數據會被保存到二級緩存中;新的會話查詢信息,就可以參照二級緩存中的內容;

* 3、不同namespace查出的數據會放在自己對應的緩存中(map):sqlSession===EmployeeMapper==>Employee|DepartmentMapper===>Department

* 二級緩存工作效果:查出的數據都會被預設先放在一級緩存中.只有會話提交或者關閉以後,一級緩存中的數據才會轉移到二級緩存中;

* 二級緩存使用:

* 1、開啟全局二級緩存配置:<setting name="cacheEnabled" value="true"/>

* 2、去需要使用二級緩存的xml中配置使用二級緩存;添加<cache></cache>

* 3POJO需要實現序列化介面

*

* 緩存有關屬性/設置:

* 1cacheEnabled="true|false": false關閉緩存(二級緩存關閉)(一級緩存一直可用的)

* 2、每個select標簽都有useCache="true|false": false不使用緩存(一級緩存依然使用,二級緩存不使用)

* 3*每個增刪改標簽的:flushCache="true|false":(一級二級都會清除)增刪改執行完成後就會清楚緩存;

* 測試:flushCache="true":一級緩存會被清空;二級也會被清空;每次查詢之後都會清空緩存,緩存是沒有被使用的;

* 4sqlSession.clearCache();只是清除當前session的一級緩存

* 5localCacheScope:本地緩存作用域;一級緩存SESSION;當前會話的所有數據保存在會話緩存中;STATEMENT:可以禁用一級緩存;

* @throws IOException

*/

2.第三方緩存整合

  EhCache 是一個純Java的進程內緩存框架,具有快速、精幹等特點,是Hibernate中預設的CacheProvider.

  MyBatis定義了Cache介面方便我們進行自定義擴展. 

參考文檔:https://mybatis.org/mybatis-3/zh/sqlmap-xml.html#cache

http://mybatis.org/ehcache-cache/index.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 第一步:父層設置文本居中屬性。第二步:li設置內聯樣式。只需以上兩步就可以實現導航欄居中顯示了,但為了美觀好看,可以稍微加點料。以下供參考:list-style:none; 取消列表前面的列表樣式border-radius:25px; 設置圓角背景樣式text-decoration:none; 取消... ...
  • 前言 響應式原理作為 Vue 的核心,使用數據劫持實現數據驅動視圖。在面試中是經常考查的知識點,也是面試加分項。 本文將會循序漸進的解析響應式原理的工作流程,主要以下麵結構進行: 分析主要成員,瞭解它們有助於理解流程 將流程拆分,理解其中的作用 結合以上的點,理解整體流程 文章稍長,但部分是代碼,還 ...
  • ●存儲大小的不同: localStorage的大小一般為5M sessionStorage的大小一般為5M cookies的大小一般為4K ●有效期不同: 1.localStorage的有效期為永久有效,除非你進行手動刪除。 2.sessionStorage在當前會話下有效,關閉頁面或者瀏覽器時會被 ...
  • 我們使用原生JS+CSS3,來開發一個集趣味性與技術性於一體的H5小游戲。我們會就地講解項目中用到的css,js基礎知識點,先舉一些小的示例,來闡明知識點的用法,再說明如何在本項目中應用,應用在哪塊功能的實現上。比如標準文檔流,定位,浮動,盒子模型,CSS3彈性盒子,CSS3高級選擇器,背景圖片,j... ...
  • 1、定位的疊放次序(只有定位的盒子才擁有這個屬性) (1)在使用定位佈局的時候,可能會出現盒子重疊的情況,此時,可以使用z-index來控制盒子的前後次序。該屬性的值可以是正整數、負整數或0,預設是auto,數值越大,盒子越靠上 <!DOCTYPE html> <html> <head> <meta ...
  • 面向對象三要素:封裝、繼承、多態。 封裝和繼承,這兩個比較好理解,但要理解多態的話,可就稍微有點難度了。今天,我們就來講講多態的理解。 我們應該經常會看到面試題目:請談談對多態的理解。 其實呢,多態非常簡單,就一句話:調用同一種方法產生了不同的結果。 具體實現方式有三種。 一、重載 重載很簡單。 p ...
  • 為什麼要搭建港股交易平臺?那就要問股民們為什麼會選擇港股進行投資了?一般的股民可能有人會說:還能為啥啊?賺錢唄!!!但是選擇投資港股,卻可能不是簡單的賺錢這麼簡單。可能很多人並不瞭解香港市場,畢竟這是一個境外市場,運作機制和操作風格都和我們熟悉的A股有很大的不同。 與A股相比,港股的優勢是比較明顯的 ...
  • smartadmin.core.urf 這個項目是基於asp.net core 3.1(最新)基礎上參照領域驅動設計(DDD)的理念,並參考目前最為了流行的abp架構開發的一套輕量級的快速開發web application 技術架構,專註業務核心需求,減少重覆代碼,開始構建和發佈,讓初級程式員也能開 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...