Mybatis的緩存機制Cache

Mybatis提供對緩存的支持,分為一級緩存和二級緩存,在沒有配置的情況下,系統默認會使用一級緩存。

一級緩存(SqlSession級別)

  我們都知道每個SqlSession對象之間的緩存是互不影響的,當同一個SqlSession執行多次相同的SQL語句時(主要針對select),系統只會到底層訪問數據庫一次,后續執行sql時,會從一級緩存里面讀取第一次訪問的數據。當這個SqlSession對象執行close(),或者顯示聲明清空緩存時,對應的一級緩存也會清空,從而提高效率。值得注意的是,如果SqlSession執行DML操作(即insert、update、delete),并提交到數據庫時,也會起到清空該SqlSession對象對應的一級緩存的作用,目的是為了保證緩存里面的數據是最新的。,避免臟讀現象。

二級緩存(SqlSessionFactory級別)

  有些書籍說二級緩存是Mapper級別,可能是依據二級緩存的配置是在xxxMapper.xml上配置的吧,不過本人更認同是SqlSessionFactory級別,為什么呢?因為同一個Configuration里面是創建一個SqlSessionFactory,SqlSessionFactory是屬于線程安全的,SqlSessionFactory可以創建很多個SqlSession來進行事務操作,也就是說,SqlSessionFactory是由很多個SqlSession對象共享的,同樣的,二級緩存的數據也是由很多個SqlSession共享的。如何才能讓系統操作二級緩存呢?原理很簡單,不同的SqlSession對象執行相同的namespace下的sql語句,當第一個SqlSession對象調用close()關閉一級緩存時,第一次查詢得到的數據將會被保存到二級緩存,后面的SqlSession對象調用相同sql語句時,就會從二級緩存中獲取數據。當然,使用二級緩存,需要對應的返回對象(即POJO)實現序列化。

配置:在需要使用的xxxMapper.xml里面配置<cache eviction="LRU" flushInterval="100000" size="1024" readOnly="true" />

eviction:代表回收策略,目前支持4種策略

1.LRU,最近最少使用的,移除最長時間不用的對象;

2.FIFO,先進先出;

3.SOFT,移除基于垃圾回收器狀態和軟引用規則的對象;

4.WEAK,更積極移除基于垃圾回收器狀態和弱引用規則的對象。

flushInterval:代表刷新時長,單位毫秒

size:代表緩存最多可以存儲多少個對象,注意,設置過大會導致內存溢出

readOnly:意味著緩存數據只能讀取,不能修改

上面是較為詳細配置,當然也可以簡單一點,直接寫上<cache />就可以了。

下面給出一個較為有意思的栗子:

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">
<mapper namespace="com.learn.mapper.EmployeeMapper"><cache /><select id="getEmpList" resultType="employee">select * from tb_employee</select></mapper>

JUnit4測試代碼如下:

@Testpublic void testCache(){SqlSession ss1 = null;SqlSession ss2 = null;try{ss1 = SqlSessionFactoryUtil.initSqlSessionFactory().openSession();ss2 = SqlSessionFactoryUtil.initSqlSessionFactory().openSession();EmployeeMapper em1 = ss1.getMapper(EmployeeMapper.class);EmployeeMapper em2 = ss2.getMapper(EmployeeMapper.class);List<Employee> list1 =  em1.getEmpList();//ss1.close();list1 = em2.getEmpList();}catch(Exception e){ss1.rollback();ss2.rollback();e.printStackTrace();}finally{if(ss1 != null){ss1.close();}if(ss2 != null){ss2.close();}}}

代碼中實例化兩個SqlSession對象,分別是ss1和ss2,用戶檢驗數據讀取的操作。留意上面注釋了ss1.close();這一行。

下面是執行上面測試代碼的日志結果:

Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Cache Hit Ratio [com.learn.mapper.EmployeeMapper]: 0.0
Opening JDBC Connection
Created connection 275310919.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1068e947]
==>  Preparing: select * from tb_employee 
==> Parameters: 
<==      Total: 6
Cache Hit Ratio [com.learn.mapper.EmployeeMapper]: 0.0
Opening JDBC Connection
Created connection 1948863195.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@74294adb]
==>  Preparing: select * from tb_employee 
==> Parameters: 
<==      Total: 6
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1068e947]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1068e947]
Returned connection 275310919 to pool.
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@74294adb]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@74294adb]
Returned connection 1948863195 to pool.

可以看到即使配置了<cache />二級緩存,第一個SqlSession對象ss1沒有手動執行close()方法時,ss1對應的一級緩存數據仍然沒有保存到二級緩存里面,即二級緩存里面沒有數據,當第二個SqlSession對象ss2執行相同的sql語句時,會找一級緩存有沒有數據,因為第一次執行,當然沒有數據了,然后找二級緩存,剛才說過了,ss1的一級緩存數據并沒有保存到二級緩存里面,所以二級緩存也沒有數據,因此ss2就會再次操作數據庫。可以看到log日志會有兩條select語句。

此時,如果將close();的注釋去掉,再執行一下測試代碼,日志結果如下:

Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Cache Hit Ratio [com.learn.mapper.EmployeeMapper]: 0.0
Opening JDBC Connection
Created connection 275310919.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1068e947]
==>  Preparing: select * from tb_employee 
==> Parameters: 
<==      Total: 6
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1068e947]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1068e947]
Returned connection 275310919 to pool.
Cache Hit Ratio [com.learn.mapper.EmployeeMapper]: 0.5

顯而易見,此時只訪問一次數據庫。

轉載于:https://www.cnblogs.com/SysoCjs/p/9574318.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/451425.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/451425.shtml
英文地址,請注明出處:http://en.pswp.cn/news/451425.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

大數據應用時代來襲 SaaS走向沒落?

隨著大量的信息涌入互聯網——90%的互聯網是過去兩年建立起來的——互聯網公司正在想方設法去熟悉并利用大數據來推動他們的業務。正如SaaS和云技術一樣完全變革了企業的運作方式一樣&#xff0c;大數據應用&#xff08;BDA&#xff09;也同樣可以。 BDA是基于網絡的應用&#…

為什么使用數據庫從庫

主庫用來進行寫操作&#xff0c;從庫用來進行讀操作&#xff0c;這樣一來的可以大大提高讀取的效率。在一般的互聯網應用中&#xff0c;經過一些數據調查得出結論&#xff0c;讀/寫的比例大概在 10&#xff1a;1左右 &#xff0c;也就是說大量的數據操作是集中在讀的操作。但是…

Java程序員必知的10個調試技巧

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 在本文中&#xff0c;作者將使用大家常用的的開發工具Eclipse來調試Java應用程序。但這里介紹的調試方法基本都是通用的&#xff0c;也適…

【GPS】GPS的C_GNSS_RF_ELNA_GPIO_NUM_DEFAULT配置,Linux系統中GPIO的設置

GPS的GPIO配置文件 客戶需要更改此變量C_GNSS_RF_ELNA_GPIO_NUM_DEFAULT才能覆蓋NAVRF驅動程序ELNA設置。   modem_proc/gps/gnss/mgp/me/gen8/src/cgps_ext.c /* Customer needs to change this variable in order to override NAVRF driver ELNA setting */ gnss_ExternalG…

學習的境界

學習是有境界的&#xff0c;下面以C語言中的結構型為例簡單分析。 第一種境界&#xff1a;理解了。 結構型是自定義數據類型&#xff0c;與C語言中基本的數據類型如int的作用相同&#xff0c;用于定義變量。&#xff08;變量是內存中存儲單元的標識&#xff0c;C語言中通過變…

性能測試的重要意義(一)

?我是一下下面幾個方面來理解的&#xff1a; 1.秒的性能對于顧客的意義&#xff1f; 2.性能測試的重要意義 3.什么是軟件的性能&#xff1f; 4.軟件的性能測試是什么&#xff1f; 5.功能測試和性能測試對比&#xff1f; 6.項目組不同角色眼中的軟件性能&#xff1f; 7.性能測試…

ContextLoaderListener介紹

在給新同事培訓Spring MVC時&#xff0c;有人問&#xff1a;可以不配置ContextLoaderListener嗎 所謂ContextLoaderListener&#xff0c;就是在web部署描述符即web.xml里面經常配置的一個監聽器&#xff0c;如下 [html] view plaincopy <listener> <listener-cl…

PLSQL安裝教程,無需oracle客戶端(解決本地需要安裝oracle客戶端的煩惱)

最近用筆記本開發&#xff0c;項目用的是Oracle數據庫&#xff0c;不想本地安裝Oracle客戶端。 就只裝了一個PLSQL 連接數據庫的時候各種錯誤&#xff0c;現在解決了記錄一下。 詳細內容見 附件 1、運行 plsqldev1105_x64.exe2、運行 Language_zh_x86_x64.exe3、啟動 plsql 點…

移動開發(C#、VB.NET)Smobiler開發平臺——GifView控件的使用方式

2019獨角獸企業重金招聘Python工程師標準>>> 一、 樣式一 我們要實現上圖中的效果&#xff0c;需要如下的操作&#xff1a; 從工具欄上的“Smobiler Components”拖動一個GifView控件到窗體界面上修改GifView的屬性 AutoPlay屬性獲得和設置是否自動播放Gif…

Spring中的計時器StopWatch

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 需要記錄每個任務執行時間&#xff0c;或者記錄一段代碼執行時間&#xff0c;簡單方法是打印當前時間與執行完時間的差值&#xff0c;若…

常用數據結構--線性結構

數據結構是計算機存儲、組織數據的方式。常見的數據結構分類方式如下圖&#xff1a; 常用的線性結構有&#xff1a;線性表&#xff0c;棧&#xff0c;隊列&#xff0c;循環隊列&#xff0c;數組。線性表中包括順序表、鏈表等&#xff0c;其中&#xff0c;棧和隊列只是屬于邏輯上…

依賴注入簡介(一)

依賴注入(Injecting dependencies)經常聽起來會讓人感覺到很難以理解&#xff0c;會讓大家感覺這是很復雜的編程技術&#xff0c;但是事實上并不是這樣&#xff0c;依賴注入非常方便使用&#xff0c;它會讓你的程序非常便于理解&#xff0c;同時也更容易進行測試。 依賴注入的…

Jmeter筆記(Ⅱ)使用Jmeter實現輕量級的接口自動化測試

接口測試雖然作為版本的一環&#xff0c;但是也是有一套完整的體系&#xff0c;有接口的功能測試、性能測試、安全測試&#xff1b;同時&#xff0c;由于接口的特性&#xff0c;接口的自動化低成本高收益的&#xff0c;使用一些開源工具或一些輕量級的方法&#xff0c;在測試用…

設置Android Studio工程布局文件的默認布局

每次創建新的工程后&#xff0c;布局文件的的布局總是ConstraintLayout&#xff0c;如何更改&#xff1f; 進入Android Studio安裝目錄&#xff0c;用文本編輯器打開文件plugins\android\lib\templates\activities\common\root\res\layout\simple.xml.ftl 將文件內容修改為 <…

依賴注入簡介(二)

在上一篇中&#xff0c;我們已經介紹過了最基本的依賴注入&#xff0c;接下來我們來看如何對需要使用的類進行裝配。通常應用程序的組件之間的關聯是通過wiring&#xff0c;在Spring中同樣有很多方式來裝配。但是一個最通常我們使用的方法是利用XML。接下來我們來展示一個簡單的…

eclipse啟動tomcat 訪問http://localhost:8080 報404錯誤

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 eclipse正常啟動tomcat&#xff0c;但是 訪問http://localhost:8080 卻報404錯誤 修改下配置 就好操作如下圖 打開eclipse的server視圖&a…

3秒搞定!~~ 一億數據獲取前100個最大值

3秒搞定&#xff01;~~ 一億數據獲取前100個最大值 整合網絡上的算法。 根據我的思路。計算一億個數字中最大的前100個值。 昨晚效率還是很低。 今天搞的算法。 只需要3秒鐘。 獲取前100個 前1000個 速度都非常快。 算法原理&#xff1a; 把一億個數字的前100個 首先放入數…

手把手JDK環境變量配置

分為下載&#xff0c;配置&#xff0c;驗證三個步驟解釋如何進行JDK環境變量配置。 步驟一&#xff1a; 首先查看配置成功后的效果&#xff1a; tip:點擊win——>運行&#xff08;或者使用winr,或者shift鼠標右鍵打開powershell&#xff09;——>輸入cmd回車——>控制…

網易NEI在面臨前后端分離問題,所提供的完整解決方案

內容來源&#xff1a;2018 年 1 月5 日&#xff0c;網易NEI產品負責人包勇明在“2018移動技術創新大會”進行《網易高效多端應用協作開發實踐》演講分享。IT 大咖說&#xff08;微信id&#xff1a;itdakashuo&#xff09;作為獨家視頻合作方&#xff0c;經主辦方和講者審閱授權…

如何使用js動態顯示或隱藏DIV

在web頁面中&#xff0c;經常需要使用select控件來顯示div的顯示與隱藏&#xff0c;實現這個方法主要用到了setAttribute方法&#xff0c;以下為示例代碼 [html] view plaincopy <html> <title>通過選擇項顯示不同的結果</title> <head> <scr…