mybatis緩存機制

mybatis緩存機制

緩存在互聯網系統中是很是重要的, 其主要做用是將數據保存到內存中, 當用戶查詢數據 時, 優先從緩存容器中獲取數據,而不是頻繁地從數據庫中查詢數據,從而提升查詢性能。目 前流行的緩存服務器有MongoDB 、Redis 、Ehcache 等,不一樣的緩存服務器有不一樣的應用場景, 不存在孰優孰劣。 MyBatis 提供一級緩存和二級緩存的機制。一級緩存是SqlSession 級別的緩存, 在操做數據 庫時, 每一個SqlSession 類的實體對象中都有一個HashMap 數據結構能夠用來緩存數據,不一樣的 SqlSession 類的實例對象緩存的HashMap 數據結構互不影響。二級緩存是Mapper 級別的緩存, 多個SqlSession 類的實例對象操做同一個Mapper 配置文件中的SQL 語句,能夠共用二級緩存, 二級緩存是跨SqlSession 的。這裏須要注意的是,在沒有配置的默認狀況下, MyBatis 只開啓一 級緩存。數據庫

My Batis 的緩存模式如圖所示:緩存

一級緩存

概述

MyBatis 的一級緩存是SqI Session 級別的緩存, 在操做數據庫時須要構造Sq!Session 對象。 每一個SqISession 對象中都有一個HashMap 對象用於緩存數據,不一樣的SqlSession 之間的緩存數 據區域互不影響。 MyBatis的一級緩存做用域是SqlSession 範圍的,在參數和SQL 徹底同樣的狀況下,使用 同一個SqlSession 對象調用同一個Mapper 方法,每每只執行一次SQL ,由於MyBatis 會將數據 放在緩存中,下次查詢的時候,若是沒有聲明須要刷新緩存而且緩存沒有超時, SqlSession 都 只會取出當前緩存的數據,而不會再次發送SQL 到數據庫中。須要注意的是,若是SqlSession 執行了DML 操做( insert 、update 和delete ),並提交到數據庫, MyBatis 會清空SqlSession 中 的一級緩存,這樣作的目的是爲了保證緩存中存儲的是最新的信息, 以免出現髒讀現象。 MyBatis 的緩存機制是基於id 進行緩存的, MyBatis 使用HashMap 緩存數據時,使用對象的id 做爲key,而對象則做爲value 保存。服務器

示例

上述代碼中,經過@Resource 註解注入SqlSessionFactoryBean 對象, SqlSessionFactoryBean 對象在applicationContext.xml 配置文件中己配置, 具體代碼以下:session

經過SqlSessionFactory 工廠獲取SqlSession 對象, 經過SqlSession 對象的getMapper()方法 獲取AyUserDao 接口對象, 並執行AyUserDao 接口對象的findByld()方法。AyUserDao 和 AyUserMapper.xml 的代碼以下所示。數據結構

執行測試用例testsessionCach e(),控制檯打印相關的信息,具體如圖9-2 所示。mybatis

由圖9 -2 中控制檯打印的信息能夠看出,第一次查詢和第二次查詢,查詢SQL 的日誌只輸 出一遍, 這就說明了第二次查詢的數據不是從數據庫查詢出來的,是從一級緩存中獲取的。app

生命週期

MyBatis 在開啓一個Session 會話時, 會建立一個新的SqISession 對象, 每一個SqlSession 對 象會建立一個新的Executor 對象, Executor 對象中持有一個新的PerpetualCache 對象: 當會話結 束時, SqISession 對象及其內部的Executor 對象還有PerpetualCache 對象也會一併釋放掉,即: (1 )若是SqlSession 調用了close()方法,會釋放掉一級緩存PerpetualCache 對象, 一級緩 存不可用。 (2 )若是SqlSession 調用了clearCache(), 會清空PerpetualCache 對象中的數據,可是該對 象仍可以使用。 ( 3 ) SqlSession 中執行任何一個DDL 操做( update 、delete 、insert) ,都會清空 PerpetualCache 對象的數據,可是該對象能夠繼續使用。性能

二級緩存

概述

二級緩存是Mapper 級別的緩存。使用二級緩存時,多個SqlSession 使用同一個Mapper ( namespace )的SQL 語句操做數據庫,獲得的數據會存在二級緩存區域,二級緩存一樣是使用 HashMap 進行數據存儲。二級緩存比一級緩存做用域範圍更大,多個SqISession 能夠共用二級 緩存,二級緩存是跨SqISession 的。當某個SqISession 類的實例對象執行了增、刪、改等操做 時, Mapper 實例會清空二級緩存。MyBatis 默認沒有開啓二級緩存,須要在配置中開啓二級緩 存。開啓二級緩存的步驟以下。測試

首先,在applicationContext.xml 配置文件中添加以下配置:spa

上面配置信息中最重要的就是指定MyBatis 配置文件的位置:

其次,在src\main\resources 目錄下添加配置文件mybatis-config . xml , 具體代碼以下:

最後,因爲二級緩存是Mapper 級別的,還要在須要開啓二級緩存的具體mapper.xml 文件 中開啓二級緩存,方法很簡單,只須要在mappe川ml 文件中添加一個cache 標籤既可,具體代 碼以下所示:

cache 標籤有不少屬性,經常使用的屬性如表9- 1 所示:

示例

AyUserDao 和AyUserMapper.xml 代碼以下:

當開啓MyBatis 二級緩存後,執行測試用例testSessionCache(), 控制檯打印相關的信息, 具體如圖9-4 所示。

由圖9-4 可知, 第一次查詢數據時, 獲取鏈接、編譯SQL、加載了數據庫中的數據。而第 二次查詢數據以前,進行了update 操做,至關於進行commit 操做,也就是說會清空一級緩存來 保證數據的最新狀態。可是開啓了二級緩存,在第二次查詢時,會從二級緩存中獲取數據。 這裏須要注意的是,若是在select 標籤中設置「 userCache = false」 能夠禁用當前select 語句 的二級緩存,具體代碼以下:

這裏簡單總結一下二級緩存的特色:

還須要注意的是,使用二級緩存須要特別謹慎,有時候不一樣的namespace 下的SQL 配置可 能緩存了相同的數據。例如AyUserMapper.xml 中有不少查詢緩存了用戶數據,其餘的 XXXMapper且nl 中有針對用戶表進行單表操做, 也緩存了用戶數據,若是在AyUserMapper.xml 中作了刷新緩存的操做,在XXXMapper.xml 中的緩存數據仍然有效, 這樣在查詢數據時可能會 出現髒數據。因此使用MyBatis 的二級緩存時,要根據具體的業務狀況,謹慎使用。

###cache-ref共享緩存

MyBatis 並非整個Application 只有一個Cache 緩存對象,它將緩存劃分的更細, 也就是 Mapper 級別的,即每個Mapper 均可以擁有一個Cache 對象,具體以下:

( 1 ) 爲每個Mapper 分配一個Cache 緩存對象(使用<cache>節點配置) 。 ( 2 )多個Mapper 共用一個Cache 緩存對象(使用<cache-ref>節點配置) 。

若是想讓多個Mapper 共用一個Cache ,可使用<cache-ref namespace="與節點,來指定這 個Mapper 共享哪個Mapper 的Cache 緩存。具體如圖9-5 所示。

mybatis緩存原理

工做原理

如圖9- 6 所示, 一個SqlSession 對象中建立一個本地緩存( local cache ),對於每次查詢, 都會根據查詢條件去一級緩存中查找,若是緩存中存在數據,就直接從緩存中取出,而後返回 給用戶:不然,從數據庫讀取數據,將查詢結果存入緩存並返回給用戶。

SqlSession 將它的工做交給了Executor 執行器這個角色來完成,負責完成對數據庫的各類 操做。當建立一個SqlSession 對象時, MyBatis 會爲這個SqlSession 對象建立一個新的Executor 執行器,而緩存信息就被維護在這個Executor 執行器中, MyBatis 將緩存和對緩存相關的操做 封裝成了Cache 接口。

如圖9 - 7 所示, MyBatis 的二級緩存機制的關鍵是使用Executor 對象。當開啓SqlSession 會 話時, 一個Session 對象使用一個Executor 對象來完成會話操做。若是用戶配置了 "cacheEnabled=true」, 那麼MyBatis 在爲SqlSession 對象建立Executor 對象時,會對Executor 對 象加上一個裝飾者: CachingExecutor ,這時SqISession 使用CachingExecutor 對象來完成操做請 求。CachingExecutor 對於查詢請求,會先判斷該查詢請求在二級緩存中是否有緩存結果,若是 有查詢結果, 則直接返回緩存結果:若是緩存中沒有, 再交給真正的Executor 對象來完成查詢 操做,以後CachingExecutor 會將真正Executor 返回的查詢結果放置到緩存中,而後再返回給 用戶。

相關文章
相關標籤/搜索