Mybatis快取詳解
什麼是Mybatis快取?
使用快取可以減少Java Application與資料庫的互動次數,從而提升程式的執行效率。比如,查詢id=1的user物件,第一次查詢出來之後,會自動將該物件儲存到快取中。下一次查詢該物件時,就可以直接從快取中獲取,不需要傳送SQL查詢資料庫了。
Mybatis快取分類
一級快取:SqlSession級別,預設開啟,且不能關閉。
mybatis的一級快取是SqlSession級別的快取,在運算元據庫時需要構造SqlSession物件,在物件中有一個HashMap用於儲存快取資料,不同的SqlSession之間快取資料區域(HashMap)是互相不影響的。
一級快取的作用域是SqlSession範圍的,當在同一個SqlSession中執行兩次相同的sql語句時,第一次執行完畢會將資料庫中查詢的資料寫到快取(記憶體)中,第二次查詢時會從快取中獲取資料,不再去底層進行資料庫查詢,從而提高了查詢效率。需要注意的是:如果SqlSession執行了DML操作(insert、update、delete),並執行commit()操作,mybatis則會清空SqlSession中的一級快取,這樣做的目的是為了保證快取資料中儲存的是最新的資訊,避免出現髒讀現象。
當一個SqlSession結束後該SqlSession中的一級快取也就不存在了,Mybatis預設開啟一級快取,不需要進行任何配置。
二級快取:Mapper級別,預設關閉,可以開啟。
二級快取是Mapper級別的快取,使用二級快取時,多個SqlSession使用同一個Mapper的sql語句去運算元據庫,得到的資料會存在二級快取區域,它同樣是使用HashMap進行資料儲存,相比一級快取SqlSession,二級快取的範圍更大,多個SqlSession可以共用二級快取,二級快取是跨SqlSession的。
二級快取是多個SqlSession共享的,其作用域是mapper的同一個namespace,不同的SqlSession兩次執行相同的namespace下的sql語句,且向sql中傳遞的引數也相同,即最終執行相同的sql語句,則第一次執行完畢會將資料庫中查詢的資料寫到快取(記憶體),第二次查詢時會從快取中獲取資料,不再去底層資料庫查詢,從而提高查詢效率。
Mybatis預設關閉二級快取,可以在setting全域性引數中配置開啟二級快取。
下面我們透過程式碼來學習如何使用MyBatis快取。
首先來演示一級快取,以查詢Student物件為例。
/**
* @ClassName Student
* @Description
* @Author lzq
* @Date 2019/7/26 13:53
* @Version 1.0
**/
public class Student {
private int SID;
private String Sname;
private String Ssex;
private int Age;
public int getSID() {
return SID;
}
public void setSID(int SID) {
this.SID = SID;
}
public String getSname() {
return Sname;
}
public void setSname(String sname) {
Sname = sname;
}
public String getSsex() {
return Ssex;
}
public void setSsex(String ssex) {
Ssex = ssex;
}
public int getAge() {
return Age;
}
public void setAge(int age) {
Age = age;
}
@Override
public String toString() {
return "[id"+SID+" 名字"+Sname+" 性別"+Ssex+" 年齡"+Age+"]";
}
}
StudentMapper介面:
import org.apache.ibatis.annotations.*;
public interface StudentMapper {
public Student getStudentById(int id);
}
mybatis-config.xml:
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"
StudentMapper.xml:
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"
select * from student where SID = #{id}
測試程式碼:
**
* @ClassName Test
* @Description
* @Author lzq
* @Date 2019/7/26 13:53
* @Version 1.0
**/
public class Test {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
//讀取配置檔案
InputStream asStream = Resources.getResourceAsStream(resource);
//建立sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(asStream);
//建立sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//透過動態代理產生StudentMapper物件
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//查詢id為1的元組
Student student = mapper.getStudentById(1);
System.out.println(student);
Student student1 = mapper.getStudentById(1);
System.out.println(student1);
}
}
可以看到結果,執行了一次SQL語句,查詢出兩個物件,第一個物件是透過SQL查詢的,並儲存到快取中,第二個物件是直接從快取中獲取的。
我們說過一級快取是SqlSession級別的,所以SqlSession一旦關閉,快取也就不復存在了,修改程式碼,再次測試。
測試程式碼:
**
* @ClassName Test
* @Description
* @Author lzq
* @Date 2019/7/26 13:53
* @Version 1.0
**/
public class Test {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
//讀取配置檔案
InputStream asStream = Resources.getResourceAsStream(resource);
//建立sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(asStream);
//建立sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//透過動態代理產生StudentMapper物件
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//查詢id為2的元組
Student student = mapper.getStudentById(1);
System.out.println(student);
sqlSession.close(); //關閉原有的sqlSession
sqlSession = sqlSessionFactory.openSession(); //建立一個新的
mapper = sqlSession.getMapper(StudentMapper.class);
Student student1 = mapper.getStudentById(1);
System.out.println(student1);
}
}
可以看到,執行了兩次SQL。
在關閉SqlSession,一級快取失效的情況下,可以啟用二級快取,實現提升效率的要求。
MyBatis可以使用自帶的二級快取,也可以使用第三方的ehcache二級快取。
自帶二級快取 無錫人流哪家好
mybatis-config.xml配置開啟二級快取
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"
在StudentMapper.xml配置中開啟二級快取:
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"
select * from student where SID = #{id}
Student類實現Serializable介面:
import java.io.Serializable;
/**
* @ClassName Student
* @Description
* @Author lzq
* @Date 2019/7/26 13:53
* @Version 1.0
**/
public class Student implements Serializable{
private int SID;
private String Sname;
private String Ssex;
private int Age;
public int getSID() {
return SID;
}
public void setSID(int SID) {
this.SID = SID;
}
public String getSname() {
return Sname;
}
public void setSname(String sname) {
Sname = sname;
}
public String getSsex() {
return Ssex;
}
public void setSsex(String ssex) {
Ssex = ssex;
}
public int getAge() {
return Age;
}
public void setAge(int age) {
Age = age;
}
@Override
public String toString() {
return "[id"+SID+" 名字"+Sname+" 性別"+Ssex+" 年齡"+Age+"]";
}
}
測試程式碼依舊是上一次用的那個:
可以看到,執行了一次SQL,查詢出兩個物件,cache命中率為0.5;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69945560/viewspace-2656601/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Mybatis 一級快取和二級快取原理區別 (圖文詳解)MyBatis快取
- MyBatis特快取性詳解MyBatis快取
- MyBatis 快取MyBatis快取
- mybatis快取-二級快取MyBatis快取
- Redis詳解(十二)------ 快取穿透、快取擊穿、快取雪崩Redis快取穿透
- Mybatis(三) 快取MyBatis快取
- 05、MyBatis 快取MyBatis快取
- Mybatis的快取MyBatis快取
- MyBatis快取機制(一級快取,二級快取)MyBatis快取
- MyBatis的快取玩法MyBatis快取
- Mybatis快取機制MyBatis快取
- Mybatis 整合 ehcache快取MyBatis快取
- 深入Nginx + PHP 快取詳解NginxPHP快取
- JuiceFS 快取預熱詳解UI快取
- 快取穿透詳解及解決方案快取穿透
- SpringBoot 下 Mybatis 的快取Spring BootMyBatis快取
- MyBatis框架原理3:快取MyBatis框架快取
- Mybatis二級快取使用MyBatis快取
- Mybatis的二級快取MyBatis快取
- MyBatis 的快取機制MyBatis快取
- mybatis的快取機制MyBatis快取
- day09-MyBatis快取MyBatis快取
- nginx快取使用詳解,nginx快取使用及配置步驟Nginx快取
- http強制快取、協商快取、指紋ETag詳解HTTP快取
- 深度詳解GaussDB bufferpool快取策略快取
- mybatis原始碼詳細解析(2)---- 一級,二級快取MyBatis原始碼快取
- Mybatis的快取——一級快取和原始碼分析MyBatis快取原始碼
- mybatis快取之一級快取(一)MyBatis快取
- mybatis快取之一級快取(二)MyBatis快取
- 瀏覽器快取機制詳解瀏覽器快取
- Mybatis的二級快取、使用Redis做二級快取MyBatis快取Redis
- Mybatis延遲載入、快取MyBatis快取
- mybatis二級快取引數MyBatis快取
- Mybatis詳解MyBatis
- Nginx 快取機制詳解!非常詳細實用Nginx快取
- myBatis原始碼解析-快取篇(2)MyBatis原始碼快取
- mybatis延遲載入和快取MyBatis快取
- 被mybatis一級快取坑了MyBatis快取