Mybatis學習筆記18 - 緩存

兩級緩存:
一級緩存:(本地緩存):sqlSession級別的緩存。一級緩存是一直開啟的;SqlSession級別的一個Map
數據庫同一次會話期間查詢到的數據會放在本地緩存中。以后如果需要獲取相同的數據,直接從緩存中拿,沒必要再去查詢數據庫。
一級緩存失效情況(沒有使用到當前一級緩存的情況,效果就是還需要再向數據庫發出查詢):
1、sqlSession不同。
2、sqlSession相同,查詢條件不同.(當前一級緩存中還沒有這個數據)
3、sqlSession相同,兩次查詢之間執行了增刪改操作(這次增刪改可能對當前數據有影響)
4、sqlSession相同,手動清除了一級緩存(緩存清空)
二級緩存全局緩存):基于namespace級別的緩存:一個namespace對應一個二級緩存:
工作機制:
1、一個會話,查詢一條數據,這個數據就會被放在當前會話的一級緩存中;
2、如果會話關閉;一級緩存中的數據會被保存到二級緩存中;新的會話查詢信息,就可以參照二級緩存中的內容;
3、不同namespace查出的數據會放在自己對應的緩存中(map)
效果:數據會從二級緩存中獲取
查出的數據都會被默認先放在一級緩存中。
只有會話提交或者關閉以后,一級緩存中的數據才會轉移到二級緩存中
使用:
1)、開啟全局二級緩存配置:<setting name="cacheEnabled" value="true"/>
2)、去mapper.xml中配置使用二級緩存:<cache></cache>

<cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024"></cache>
eviction:緩存的回收策略:
  LRU – 最近最少使用的:移除最長時間不被使用的對象。
  FIFO – 先進先出:按對象進入緩存的順序來移除它們。
  SOFT – 軟引用:移除基于垃圾回收器狀態和軟引用規則的對象。
  WEAK – 弱引用:更積極地移除基于垃圾收集器狀態和弱引用規則的對象。
  默認的是 LRU。
flushInterval:緩存刷新間隔,緩存多長時間清空一次,默認不清空,設置一個毫秒值
readOnly:是否只讀:
  true:只讀;mybatis認為所有從緩存中獲取數據的操作都是只讀操作,不會修改數據。mybatis為了加快獲取速度,直接就會將數據在緩存中的引用交給用戶。不安全,速度快
  false:非只讀:mybatis覺得獲取的數據可能會被修改。mybatis會利用序列化&反序列的技術克隆一份新的數據給你。安全,速度慢
size:緩存存放多少元素;
type:指定自定義緩存的全類名,實現Cache接口即可;

3)、POJO需要實現序列化接口

和緩存有關的設置/屬性:
1)、cacheEnabled=true:false:關閉緩存(二級緩存關閉)(一級緩存一直可用的)
2)、每個select標簽都有useCache="true":
false:不使用緩存(一級緩存依然使用,二級緩存不使用)
3)、【每個增刪改標簽的:flushCache="true":(一級二級都會清除)】
增刪改執行完成后就會清楚緩存;
測試:flushCache="true":一級緩存就清空了;二級也會被清除;
查詢標簽:flushCache="false":
  如果flushCache=true;每次查詢之后都會清空緩存;緩存是沒有被使用的;
4)、sqlSession.clearCache();只是清楚當前session的一級緩存;
5)、localCacheScope:本地緩存作用域(一級緩存SESSION);當前會話的所有數據保存在會話緩存中;STATEMENT:可以禁用一級緩存。 ? ? ?
第三方緩存整合:
1)、導入第三方緩存包即可;
2)、導入與第三方緩存整合的適配包;官方有;
3)、mapper.xml中使用自定義緩存
<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>

一、測試緩存效果

示例代碼:

接口定義:
package com.mybatis.dao;import com.mybatis.bean.Employee;public interface EmployeeMapper {public Employee getEmpById(Integer id);
}mapper定義:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.dao.EmployeeMapper"><select id="getEmpById" resultType="com.mybatis.bean.Employee">select * from tbl_employee where id=#{id}</select>
</mapper>測試代碼:
package com.mybatis.demo;import com.mybatis.bean.Employee;
import com.mybatis.dao.EmployeeMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;import java.io.IOException;
import java.io.InputStream;public class MyTest {public SqlSessionFactory getSqlSessionFactory() throws IOException {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);return new SqlSessionFactoryBuilder().build(inputStream);}@Testpublic void test() throws IOException {SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();SqlSession openSession = sqlSessionFactory.openSession(true);SqlSession openSession2 = sqlSessionFactory.openSession();try {EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);Employee emp1 = mapper.getEmpById(1);System.out.println(emp1);System.out.println("---------");Employee emp2 = mapper.getEmpById(1);System.out.println(emp2);System.out.println(emp1 == emp2);System.out.println(emp1.equals(emp2));} finally {openSession.close();}}
}

二、一級緩存失效情況

示例代碼:

接口定義:
package com.mybatis.dao;import com.mybatis.bean.Employee;public interface EmployeeMapper {public Employee getEmpById(Integer id);public void addEmp(Employee emp);
}mapper定義:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.dao.EmployeeMapper"><select id="getEmpById" resultType="com.mybatis.bean.Employee">select * from tbl_employee where id=#{id}</select><insert id="addEmp">insert into tbl_employee (last_name, email, gender, d_id)values (#{lastName},#{email},#{gender},#{dept.id})</insert>
</mapper>測試代碼:
package com.mybatis.demo;import com.mybatis.bean.Department;
import com.mybatis.bean.Employee;
import com.mybatis.dao.EmployeeMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;import java.io.IOException;
import java.io.InputStream;public class MyTest {public SqlSessionFactory getSqlSessionFactory() throws IOException {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);return new SqlSessionFactoryBuilder().build(inputStream);}//一級緩存失效情況(沒有使用到當前一級緩存的情況,效果就是還需要再向數據庫發出查詢)://1、sqlSession不同。@Testpublic void test() throws IOException {SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();SqlSession openSession = sqlSessionFactory.openSession(true);SqlSession openSession2 = sqlSessionFactory.openSession();try {EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);EmployeeMapper mapper2 = openSession2.getMapper(EmployeeMapper.class);Employee emp1 = mapper.getEmpById(1);System.out.println(emp1);System.out.println("---------");Employee emp2 = mapper2.getEmpById(1);System.out.println(emp2);System.out.println(emp1 == emp2);System.out.println(emp1.equals(emp2));} finally {openSession.close();openSession2.close();}}//2、sqlSession相同,查詢條件不同.(當前一級緩存中還沒有這個數據)@Testpublic void test2() throws IOException {SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();SqlSession openSession = sqlSessionFactory.openSession(true);try {EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);Employee emp1 = mapper.getEmpById(1);System.out.println(emp1);System.out.println("---------");Employee emp2 = mapper.getEmpById(8);System.out.println(emp2);System.out.println(emp1 == emp2);System.out.println(emp1.equals(emp2));} finally {openSession.close();}}//3、sqlSession相同,兩次查詢之間執行了增刪改操作(這次增刪改可能對當前數據有影響)@Testpublic void test3() throws IOException {SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();SqlSession openSession = sqlSessionFactory.openSession(true);try {EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);Employee emp1 = mapper.getEmpById(1);System.out.println(emp1);mapper.addEmp(new Employee(null, "haohao", "haohao@gmail.com", 1, new Department(2)));System.out.println("----數據添加成功----- ");Employee emp2 = mapper.getEmpById(1);System.out.println(emp2);System.out.println(emp1 == emp2);System.out.println(emp1.equals(emp2));} finally {openSession.close();}}//4、sqlSession相同,手動清除了一級緩存(緩存清空)@Testpublic void test4() throws IOException {SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();SqlSession openSession = sqlSessionFactory.openSession(true);try {EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);Employee emp1 = mapper.getEmpById(1);System.out.println(emp1);openSession.clearCache();Employee emp2 = mapper.getEmpById(1);System.out.println(emp2);System.out.println(emp1 == emp2);System.out.println(emp1.equals(emp2));} finally {openSession.close();}}
}

三、二級緩存的使用

示例代碼:

接口定義:
package com.mybatis.dao;import com.mybatis.bean.Employee;public interface EmployeeMapper {public Employee getEmpById(Integer id);
}mapper定義:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.dao.EmployeeMapper"><!--eviction:緩存的回收策略:LRU – 最近最少使用的:移除最長時間不被使用的對象。FIFO – 先進先出:按對象進入緩存的順序來移除它們。SOFT – 軟引用:移除基于垃圾回收器狀態和軟引用規則的對象。WEAK – 弱引用:更積極地移除基于垃圾收集器狀態和弱引用規則的對象。默認的是 LRU。flushInterval:緩存刷新間隔緩存多長時間清空一次,默認不清空,設置一個毫秒值readOnly:是否只讀:true:只讀;mybatis認為所有從緩存中獲取數據的操作都是只讀操作,不會修改數據。mybatis為了加快獲取速度,直接就會將數據在緩存中的引用交給用戶。不安全,速度快false:非只讀:mybatis覺得獲取的數據可能會被修改。mybatis會利用序列化&反序列的技術克隆一份新的數據給你。安全,速度慢size:緩存存放多少元素;type="":指定自定義緩存的全類名;實現Cache接口即可;--><cache/><select id="getEmpById" resultType="com.mybatis.bean.Employee">select * from tbl_employee where id=#{id}</select>
</mapper>測試代碼:
package com.mybatis.demo;import com.mybatis.bean.Employee;
import com.mybatis.dao.EmployeeMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;import java.io.IOException;
import java.io.InputStream;public class MyTest {public SqlSessionFactory getSqlSessionFactory() throws IOException {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);return new SqlSessionFactoryBuilder().build(inputStream);}/*** 使用:* 1)、開啟全局二級緩存配置:<setting name="cacheEnabled" value="true"/>* 2)、去mapper.xml中配置使用二級緩存:<cache></cache>** <cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024"></cache>* eviction:緩存的回收策略:*   LRU – 最近最少使用的:移除最長時間不被使用的對象。*   FIFO – 先進先出:按對象進入緩存的順序來移除它們。*   SOFT – 軟引用:移除基于垃圾回收器狀態和軟引用規則的對象。*   WEAK – 弱引用:更積極地移除基于垃圾收集器狀態和弱引用規則的對象。*   默認的是 LRU。* flushInterval:緩存刷新間隔,緩存多長時間清空一次,默認不清空,設置一個毫秒值* readOnly:是否只讀:*   true:只讀;mybatis認為所有從緩存中獲取數據的操作都是只讀操作,不會修改數據。mybatis為了加快獲取速度,直接就會將數據在緩存中的引用交給用戶。不安全,速度快*   false:非只讀:mybatis覺得獲取的數據可能會被修改。mybatis會利用序列化&反序列的技術克隆一份新的數據給你。安全,速度慢* size:緩存存放多少元素;* type:指定自定義緩存的全類名,實現Cache接口即可;* <p>* 3)、POJO需要實現序列化接口*/@Testpublic void test() 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();//第二次查詢是從二級緩存中拿到的數據,并沒有發送新的sqlEmployee emp02 = mapper2.getEmpById(1);System.out.println(emp02);openSession2.close();} finally {}}
}

?

轉載于:https://www.cnblogs.com/xidian2014/p/10352302.html

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

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

相關文章

2.7 deque

#include<deque> 雙端隊列容器 注意&#xff1a;頭入隊時伴隨的是尾出隊&#xff1b;提供中間元素的更新和刪除操作。 與vector一樣&#xff0c;采用線性表順序存儲結構 deque采用分塊的線性存儲結構來存儲數據&#xff0c;每塊大小一般為512字節 所有deque塊由一個…

APK 加殼方法

下載工具http://download.csdn.net/download/sys025/8958363一款免費的為apk加固的工具。 特別說明&#xff1a;加固后需要重新簽名apk才能安裝。加固的apk包會比未加固的大一些。 jarsigner -verbose -keystore dms.keystore -storepass pactera -keypass pactera -sigfile CE…

Java DSL簡介(收集整理)

一、領域特定語言&#xff08;DSL&#xff09; 領域特定語言&#xff08;DSL&#xff09;通常被定義為一種特別針對某類特殊問題的計算機語言&#xff0c;它不打算解決其領域外的問題。對于DSL的正式研究已經持續很多年&#xff0c;直 到最近&#xff0c;在程序員試圖采用最易讀…

[轉]JSon數據解析的四種方式

轉至http://blog.csdn.net/enuola/article/details/7903632 作為一種輕量級的數據交換格式&#xff0c;json正在逐步取代xml&#xff0c;成為網絡數據的通用格式。 有的json代碼格式比較混亂&#xff0c;可以使用此“http://www.bejson.com/”網站來進行JSON格式化校驗&#xf…

2.8 list

#include<list> 雙向循環鏈表 list結點的三個域&#xff1a;數據域、前驅元素指針域、后繼元素指針域 對于list的迭代器&#xff0c;只有或--的操作&#xff0c;無n或-n的操作 創建list對象&#xff1a; list<int> l; list<int> l(10); 插入和遍歷&…

Spring AOP兩種實現機制是什么?

Spring AOP兩種實現機制是什么&#xff1f; 1.如果是有接口聲明的類進行AOP 時&#xff0c;spring調用的是java.lang.reflection.Proxy 類來做處理 2.如果是沒有接口聲明的類時&#xff0c; spring通過cglib包和內部類來實現 在AOP&#xff0c;權限控制&#xff0c;事務管理等…

iOS開發UI篇—Quartz2D使用(繪圖路徑)

1 //1.獲取圖形上下文 2 CGContextRef ctxUIGraphicsGetCurrentContext(); 3 //2.繪圖&#xff08;畫線&#xff09; 4 //設置起點 5 CGContextMoveToPoint(ctx, 20, 20); 6 //設置終點 7 CGContextAddLineToPoint(ctx, 200, 300); 8 //渲染 9…

2.9 bitset

#include<bitset> bitset容器是一個bit位元素的序列容器&#xff0c;每個元素只占一個bit位&#xff0c;取值為0或1&#xff0c;因而很節省內存空間。 bitset<n> b; b.any() 是否有1 b.none() 是否無1 b.count() 1的個數 b.size() 大小 b[pos] 訪問 b.…

C# 談談Interface和通過Interface傳遞web頁面數據

接口&#xff1a;描述可屬于任何類或結構的一組相關功能&#xff0c;通過interface關鍵字來聲明&#xff1b;接口只包含方法、委托或事件和屬性的簽名&#xff08;接口包含的成員&#xff09;、不能包含字段&#xff08;因為字段是包含數據的&#xff09;。方法的實現是“繼承”…

Spring支持如下5種作用域

當通過Spring容器創建一個Bean實例時&#xff0c;不僅可以完成Bean實例的實例化&#xff0c;還可以為Bean指定特定的作用域。Spring支持如下5種作用域&#xff1a; singleton&#xff1a;單例模式&#xff0c;在整個Spring IoC容器中&#xff0c;使用singleton定義的Bean將只有…

RBAC授權

給用戶授予RBAC權限沒有權限會報如下錯誤&#xff1a;執行查看資源報錯&#xff1a; unable to upgrade connection: Forbidden (userkubernetes, verbcreate, resourcenodes, subresourceproxy)[roottest4 ~]# kubectl exec -it http-test-dm2-6dbd76c7dd-cv9qf sh error: una…

出卷子

http://chujuanzi.com/ 出卷子 涵蓋初高中全部學科題庫&#xff0c;全國名校試卷最快更新。試卷新、試題全、解析準、完全免費&#xff0c;提供豐富試題輔助教師有效出試卷&#xff0c;組卷方便快捷。&#xff08;高中語文 高中數學 高中英語 高中物理 高中化學 高中生物 高中政…

2.10 stack

#include<stack> 后進先出 Last In First Out LIFO 插入和刪除元素只能在表的一端進行。 插入端 棧頂 Stack Top 入棧 Push 刪除端 棧底 Stack Bottom 出棧 Pop stack<int> s; s.push(1); //入棧 int i s.top(); //獲得棧頂元素 s.pop(); //出棧 s.size…

13結構型模式之橋接模式

概念 Bridge 模式又叫做橋接模式&#xff0c;是構造型的設計模式之一。Bridge模式基于類的最小設計原則&#xff0c;通過使用封裝&#xff0c;聚合以及繼承等行為來讓不同的類承擔不同的責任。它的主要特點是把抽象&#xff08;abstraction&#xff09;與行為實現&#xff08;i…

話說Svn與Git的區別

把第一條理解到位思想到位了做起來才會有的放矢&#xff0c;其他幾條都是用的時候才能體會到 1) 最核心的區別Git是分布式的&#xff0c;而Svn不是分布的。能理解這點&#xff0c;上手會很容易&#xff0c;聲明一點Git并不是目前唯一的分布式版本控制系統&#xff0c;還有比如M…

Ubuntu下Postgres安裝與配置

postgres8.4安裝配置&#xff1a;1.安裝postgres8.4~$ sudo apt-get install postgresql 2.修改超級管理員postgres密碼&#xff1a;以系統用戶運行psql~$ sudo -u postgres psql postgres修改postgres密碼(123456)postgres# /password postgres 3.備份修改的配置文件&#xff…

2.11 queue

#include<queue> 先進先出&#xff08;First In First Out, FIFO&#xff09; 隊尾插入&#xff0c;隊首刪除 queue<int> q; q.push(1); //入隊 int qf q.front(); //獲取隊首元素 int qe q.back(); //獲取隊尾元素 q.pop(); //出隊 q.size(); //大小 q.…

簡易中控紫貓插件版(3)壓縮包使用說明

1.環境配置腳本運行環境&#xff1a;沒什么說的 正常的最新版手機按鍵 當然還需要 最新的紫貓插件中控運行環境&#xff1a;首先要保證把壓縮包的所有php文件都扔到網站的根目錄下 必須保證網站的php版本是5.4 不然紫貓插件的php框架會出問題 然后你要知道網站數據庫的賬號和密…

Java9新特性

Java 8 發布三年多之后&#xff0c;即將快到2017年7月下一個版本發布的日期了。 你可能已經聽說過 Java 9 的模塊系統&#xff0c;但是這個新版本還有許多其它的更新。 這里有九個令人興奮的新功能將與 Java 9 一起發布。 1. Java 平臺級模塊系統 Java 9 的定義功能是一套全新的…

IOS 應用中從豎屏模式強制轉換為橫屏模式

在 iPhone 應用里&#xff0c;有時我們想強行把顯示模式從縱屏改為橫屏&#xff08;反之亦然&#xff09;&#xff0c;CocoaChina 會員 “alienblue” 為我們提供了兩種思路第一種&#xff1a;通過人為的辦法改變view.transform的屬性。具體辦法&#xff1a;view.transform一般…