mybatis從入門到精通,第四篇《一二級緩存》,乾貨滿滿

2020-11-06 Java菜鳥LM

MyBatis 內置了一個強大的事務性查詢緩存機制(目的:優化查詢效率),它可以非常方便地配置和定製。 為了使它更加強大而且易於配置, MyBatis 3 中的緩存實現進行了許多改進。默認情況下,只啟用了本地的會話緩存,它僅僅對一個會話中的數據進行緩存。 要啟用全局的二級緩存,只需要在你的 SQL 映射文件中進行配置。

一級緩存:基於SqlSession級別

基於SqlSession級別的,簡單來說就是SqlSession未關閉的時候,對於同一條SQL語句的話,二次執行的時候,同個SqlSession只會執行一條SQL語句到資料庫當中進行查詢;

1、EmpMapper.java

public interface EmpMapper { /** * 根據僱員編號查詢僱員信息 * @param empno * @return */ Emp queryEmpByEmpno(Integer empno);}

2、EmpMapper.xml

<mapper namespace="com.cnlm.mapper.EmpMapper"> <select id="queryEmpByEmpno" resultType="com.cnlm.pojo.Emp"> select * from emp where empno = #{empno} </select></mapper>

3、SqlSessionCacheTest.java

測試代碼:SqlSession未關閉

public class SqlSessionCacheTest { SqlSessionFactory sqlSessionFactory; SqlSession sqlSession; @Before public void before() throws IOException { //當執行Test測試前都會首先執行此方法 String resource = "mybatis.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //獲取SqlSession對象 sqlSession = sqlSessionFactory.openSession(true); } @Test public void queryEmpListTest(){ EmpMapper empMapper1 = sqlSession.getMapper(EmpMapper.class); Emp empList1 = empMapper1.queryEmpByEmpno(7844); System.out.println(empList1); /** * SqlSession未關閉的時候,對於同一條SQL語句的話,二次執行的時候, * 同個SqlSession只會執行一條SQL語句到資料庫當中進行查詢。 */ EmpMapper empMapper2 = sqlSession.getMapper(EmpMapper.class); Emp empList2 = empMapper2.queryEmpByEmpno(7844); System.out.println(empList2); }}

SqlSession未關閉測試結果:

測試代碼:SqlSession關閉

public class SqlSessionCacheTest { SqlSessionFactory sqlSessionFactory; SqlSession sqlSession; @Before public void before() throws IOException { //當執行Test測試前都會首先執行此方法 String resource = "mybatis.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //獲取SqlSession對象 sqlSession = sqlSessionFactory.openSession(true); } @Test public void queryEmpListTest(){ EmpMapper empMapper1 = sqlSession.getMapper(EmpMapper.class); Emp empList1 = empMapper1.queryEmpByEmpno(7844); System.out.println(empList1); sqlSession.close(); //關閉sqlSession sqlSession = sqlSessionFactory.openSession(); EmpMapper empMapper2 = sqlSession.getMapper(EmpMapper.class); Emp empList2 = empMapper2.queryEmpByEmpno(7844); System.out.println(empList2); }}

SqlSession關閉測試結果:

測試結論:基於SqlSession級別的,簡單來說就是SqlSession未關閉的時候,對於同一條SQL語句的話,二次執行的時候,同個SqlSession只會執行一條SQL語句到資料庫當中進行查詢。如果SqlSession關閉,二次執行的時候,不同的SqlSession也會執行2條SQL語句到資料庫當中進行查詢,當然如果還想從二級緩存sqlSessionFactory中獲取數據,可以配置開啟二級緩存。

一級緩存:基於sqlSessionFactory級別

二級緩存:這個是基於sqlSessionFactory或NameSpace級別的,也就是一個Dao或者是一個Mapper級別的。根據如上一級緩存測試,當SqlSession關閉,二次執行的時候,不同的SqlSession也會執行2條SQL語句到資料庫當中進行查詢,當然如果還想從二級緩存sqlSessionFactory中獲取數據,可以配置開啟二級緩存。

1、EmpMapper.java

public interface EmpMapper { /** * 根據僱員編號查詢僱員信息 * @param empno * @return */ Emp queryEmpByEmpno(Integer empno);}

2、EmpMapper.xml

<mapper namespace="com.cnlm.mapper.EmpMapper">
<!--啟用全局的二級緩存-->
<cache readOnly="true" />
<select id="queryEmpByEmpno" resultType="com.cnlm.pojo.Emp">
select * from emp where empno = #{empno}
</select>
</mapper>

3、SqlSessionFactoryCacheTest.java

public class SqlSessionFactoryCacheTest { SqlSessionFactory sqlSessionFactory; SqlSession sqlSession; @Before public void before() throws IOException { //當執行Test測試前都會首先執行此方法 String resource = "mybatis.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //獲取SqlSession對象 sqlSession = sqlSessionFactory.openSession(true); } @Test public void queryEmpListTest(){ EmpMapper empMapper1 = sqlSession.getMapper(EmpMapper.class); Emp empList1 = empMapper1.queryEmpByEmpno(7844); System.out.println(empList1); sqlSession.close(); //關閉sqlSession sqlSession = sqlSessionFactory.openSession(); EmpMapper empMapper2 = sqlSession.getMapper(EmpMapper.class); Emp empList2 = empMapper2.queryEmpByEmpno(7844); System.out.println(empList2); }}

測試結果:

注意:二級緩存是事務性的。這意味著,當 SqlSession 完成並提交時,或是完成並回滾,但沒有執行 flushCache=true 的 insert/delete/update 語句時,緩存會獲得更新。

演示代碼結構圖

誰在最需要的時候輕輕拍著我肩膀,誰在最快樂的時候願意和我分享。我是一個包夜敲代碼,想靠技術苟且的程式設計師。如果覺得有點用的話,請毫不留情地關注、點讚、轉發。這將是我寫出更多優質文章的最強動力!

相關焦點

  • Mybatis 一級緩存、二級緩存
    >總結:如果用相同的SqlSession對象查詢相同的數據,則只會在第一次查詢時發送Sql語句,並將這個查詢的結果放入到Sqlsession中(作為緩存存在);後續再次查詢該同意的對象時,則直接從緩存中查詢該對象即可(即省略了資料庫的訪問)二級緩存首先,這個Mybatis自帶二級緩存;也有三方提供的二級緩存;Mybatis
  • mybatis從入門到精通,第一篇《入門基本搭建》,乾貨滿滿
    Mybatis是一款優秀的高輕量級、半自動的ORM(對象關係映射--引入mybatis依賴--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency&
  • mybatis從入門到精通,第四篇《關係映射》,乾貨滿滿
    OneToOneTestpublic class OneToOneTest { SqlSessionFactory sqlSessionFactory; SqlSession sqlSession; @Before public void before() throws IOException { String resource = "mybatis.xml
  • Mybatis一級緩存和二級緩存的產生和銷毀
    一、MyBatis一級緩存 1.開啟二級緩存: 1.mybatis.xml->configuration二級緩存的命中原則 在同一個SqlSessionFactory中命中原則和一級緩存一樣4.二級緩存什麼時候產生,什麼時候銷毀 產生條件:1.滿足一級緩存產生條件 2.sqlSession執行了close或commit 一級緩存和二級緩存聯合工作的原理
  • mybatis從入門到精通,第二篇《參數傳遞》,乾貨滿滿
    mybatis 框架的主要工作是數據訪問層, 側重於與資料庫打交道的sql語句的編寫,要求對SQL也要求比較熟練。mybatis 傳遞參數的方式主要有如下⑤種:salesman");emp.setSal(new BigDecimal("3000"));List<Emp> empList = empMapper.queryEmpListByEmp(emp);在mybatis
  • 別愣著了,Slay全場的MyBatis如何精通?阿里P8看完這篇直呼內行
    MyBatis 是如何為二級緩存動態添加日誌、同步控制、阻塞、緩存淘汰策略等附加能力的?用了什麼設計模式?請描述從資料庫連接池獲取一個數據連接的過程;什麼是緩存雪崩?如何解決?能夠很好的回答出這5個問題的朋友那你對於MyBatis已經有比較深入的了解了,那對於沒法很好的回答出來的朋友來說,那你還是應該學習學習的,畢竟MyBatis作為一個ORM框架,在市面上也是非常受歡迎的,入門很簡單,只要有JDBC基礎就差不多了,但是要精通的話並不是一件簡單的事了
  • Mybatis緩存詳解
    mybatis是一個查詢資料庫的封裝框架,主要是封裝提供靈活的增刪改sql,開發中,service層能夠通過mybatis組件查詢和修改資料庫中表的數據;作為查詢工具,mybatis有使用緩存,這裡講一下mybatis的緩存相關源碼。
  • Mybatis基本知識十五:查詢緩存之二級查詢緩存(內置)
    1.引子上一章節講解了Mybatis的一級查詢緩存,一級查詢緩存是Mybatis內置的且默認開啟不可關閉。本章節將講解Mybatis內置二級查詢緩存的配置與應用。與一級查詢緩存不同,二級查詢緩存是可配置的並且生命周期是與整個應用同步的。
  • mybatis從入門到精通,第三篇《動態SQL》,乾貨滿滿
    使用動態 SQL 並非一件易事,但藉助可用於任何 SQL 映射語句中的強大的動態 SQL 語言,MyBatis 顯著地提升了這一特性的易用性。當使用可迭代對象或者數組時,index 是當前迭代的序號,item 的值是本次迭代獲取到的元素。當使用 Map 對象(或者 Map.Entry 對象的集合)時,index 是鍵,item 是值。
  • Mybatis第三講 緩存與註解
    1、 Mybatis 一對多,多對一配置2、 Mybatis 動態SQL3、 Mybatis 調用存儲過程 2.2本章知識點1、 Mybatis 一級緩存原理2、 Mybatis 二級緩存配置3、 Mybatis 事務原理4、 Mybatis 註解配置
  • MyBatis 緩存的使用,看這篇就夠了
    在日常工作中,我們大多使用MyBatis的默認緩存配置,但是MyBatis緩存機制也有一些不足之處,一不留神就會出現髒數據,形成一些潛在的隱患,後續排查問題容易浪費時間精力。所以,如何用好MyBatis的緩存,是重中之重的。
  • 關於 Mybatis 緩存的那點事兒,你知道嗎?
    如果二緩存開啟,首先從二級緩存查詢數據,如果二級緩存有則從二級緩存中獲取數據,如果二級緩存沒有,從一級緩存找是否有緩存數據,如果一級緩存沒有,查詢資料庫。3.二級緩存局限性mybatis 二級緩存對細粒度的數據級別的緩存實現不好,對同時緩存較多條數據的緩存,比如如下需求:對商品信息進行緩存,由於商品信息查詢訪問量大,但是要求用戶每次都能查詢最新的商品信息,此時如果使用 mybatis 的二級緩存就無法實現當一個商品變化時只刷新該商品的緩存信息而不刷新其它商品的信息,因為
  • Mybatis基本知識十六:查詢緩存之第三方查詢緩存
    1.引子上一章節講解了Mybatis內置的二級查詢緩存,本章節講解第三方緩存產品ehcache的應用。overflowToDisk - 設定當內存緩存溢出的時候是否將過期的element緩存到磁碟上timeToIdleSeconds - 當緩存在EhCache中的數據前後兩次訪問的時間超過timeToIdleSeconds的屬性取值時,這些數據便會刪除,默認值是0,也就是可閒置時間無窮大。單位秒。
  • 給我五分鐘,帶你徹底掌握MyBatis的緩存工作原理
    自然的,作為一款優秀的ORM框架,MyBatis中又豈能少得了緩存,那麼本文的目的就是帶領大家一起探究一下MyBatis的緩存是如何實現的。首先讓我們來想一想,既然一級緩存的作用域只對同一個SqlSession有效,那麼一級緩存應該存儲在哪裡比較合適是呢?
  • 你不知道的Mybatis的一級、二級緩存
    Mybatis的一級、二級緩存這也是一個面試大概率會問到的一個問題,一般簡歷上面都有寫熟悉SQL優化什麼的,不知道怎麼優化的可以看下面這篇文章。而Mybaits作為大多數公司用的持久層框架,一級二級緩存概念也是經常被問到的,下面就結合概念和實戰來寫一下什麼是Mybaits的一級、二級緩存!1、什麼是緩存?
  • 2020年最新中高級面試MyBatis靈魂27問?入門到精通
    (3)通過xml 文件或註解的方式將要執行的各種 statement 配置起來,並通過java對象和 statement中sql的動態參數進行映射生成最終執行的sql語句,最後由mybatis框架執行sql並將結果映射為java對象並返回。(從執行sql到返回result的過程)。
  • 阿里打磨出來的 MyBatis+設計模式 架構指南
    Mybatis快速入門Mybatis工作流程完成CRUD操作動態SQL入門總結Mybatis配置信息映射文件佔位符+Mapper代理+逆向工程Mybatis緩存Mybatis一級緩存Mybatis二級緩存Mybatis二級緩存配置查詢結果映射的pojo序列化禁用二級緩存刷新緩存了解Mybatis緩存的一些參數
  • MyBatis:緩存,延遲加載,註解應用
    SQL 到資料庫。getMapper(UserMapper.class);    // 第一次查詢    User user = userMapper1.findById(1);    System.out.println(user);    // 只有執行 sqlSession.commit 或者 sqlSession.close,那麼一級緩存中內容才會刷新到二級緩存
  • 老生常談:MyBatis的一級緩存、二級緩存、涉及的設計模式
    作者|搜l搜|簡書一、什麼是緩存四、MyBatis的二級緩存一級緩存是基於SqlSession對象的,也就是一次資料庫會話期間。而二級緩存是則是基於全局的。二級緩存的存在形式如圖:1️⃣二級緩存使用場景類似於這種統計排行榜這種的查詢,可能會涉及到很多張表很多欄位的查詢統計排序
  • 面試官口中的Mybatis,工作流程、架構分層模塊劃分以及緩存機制
    一、MyBatis的工作流程1.1 解析配置文件(Configuration)mybatis啟動的時候需要解析配置文件,包括全局配置文件和映射器配置文件,我們會把它們解析成一個Configuration對象。