最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis一級緩存與二級緩存原理與作用分析

 更新時間:2022年12月27日 11:21:53   作者:一個雙子座的Java攻城獅  
mybatis-plus是一個Mybatis的增強工具,在Mybatis的基礎(chǔ)上只做增強不做改變,為簡化開發(fā)、提高效率而生,這篇文章帶你了解Mybatis的一級和二級緩存

緩存的作用

在 Web 系統(tǒng)中,最重要的操作就是查詢數(shù)據(jù)庫中的數(shù)據(jù)。但是有些時候查詢數(shù)據(jù)的頻率非常高,這是很耗費數(shù)據(jù)庫資源的,往往會導(dǎo)致數(shù)據(jù)庫查詢效率極低,影響客戶的操作體驗。于是可以將一些變動不大且訪問頻率高的數(shù)據(jù),放置在一個緩存容器中,用戶下一次查詢時就從緩存容器中獲取結(jié)果。

MyBatis 的緩存結(jié)構(gòu)

MyBatis 系統(tǒng)中默認(rèn)定義了兩級緩存:一級緩存和二級緩存:

MyBatis 一級緩存是一個 SqlSession 級別,Sqlsession 只能訪問自己的一級緩存的數(shù)據(jù)。

二級緩存是跨 sqlSession,是 mapper 級別的緩存,對于 mapper 級別的緩存不同的 sqlsession 是可以共享的。

MyBatis 默認(rèn)開啟一級緩存,同時為了增強擴展性,MyBatis 定義了緩存接口 Cache,可以通過 Cache 自定義二級緩存。

一級緩存

MyBatis 一級緩存是一個 SqlSession 級別的緩存,緩存的執(zhí)行遵循下方的規(guī)則:

  • 映射語句文件中的所有 select 語句的結(jié)果將會被緩存。
  • 映射語句文件中的所有 insert、update 和 delete 語句會刷新緩存。
  • 緩存默認(rèn)會使用最近最少使用算法(LRU, Least Recently Used)算法來清除不需要的緩存。
  • 緩存不會定時進行刷新(也就是說,沒有刷新間隔)。
  • 緩存會保存列表或?qū)ο螅o論查詢方法返回哪種)的 1024 個引用。
  • 緩存會被視為讀/寫緩存,這意味著獲取到的對象并不是共享的,可以安全地被調(diào)用者修改,而不干擾其他調(diào)用者或線程所做的潛在修改。

接下來通過代碼模擬一級緩存的執(zhí)行,用的代碼是最簡單的一個用戶類,首先第一步在 mybatis-config 中開啟 log 日志:

<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

編寫測試代碼,在同樣的查詢條件下查詢第二次:

public class CacheTest1 {
    public static void main(String[] args) {
        // 獲取SqlSession
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        // 執(zhí)行Sql
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user=mapper.getUserById(1);
        System.out.println(user);
        //同樣的條件查詢第二次
        User user2=mapper.getUserById(1);
        System.out.println(user2);
        sqlSession.close();
    }
}

首先這段代碼是在一個 SqlSession 下,因此默認(rèn)開啟了一級緩存,在結(jié)果中可以看到,第一次查詢走的是數(shù)據(jù)庫,第二次就不需要再查數(shù)據(jù)庫了。滿足第一條規(guī)則:

映射語句文件中的所有 select 語句的結(jié)果將會被緩存。

修改條件,在查詢第二次之前先往表里插入一條數(shù)據(jù):

public class CacheTest2 {
    public static void main(String[] args) {
        // 獲取SqlSession
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        // 執(zhí)行Sql
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user=mapper.getUserById(1);
        System.out.println(user);
        //第二次查詢前先插入一條數(shù)據(jù)
        User user1=new User(5,"java");
        mapper.insertUser(user1);
        //同樣的條件查詢第二次
        User user2=mapper.getUserById(2);
        System.out.println(user2);
        sqlSession.close();
    }
}

在第一次查詢之后插入了一條數(shù)據(jù),第二次同樣條件查詢時沒有走緩存,再次查表,符合規(guī)則:

映射語句文件中的所有 insert、update 和 delete 語句會刷新緩存。

二級緩存

二級緩存的作用域比一級緩存要更大,二級緩存是 mapper 級別的緩存,你也可以理解為他是一個 namespace 內(nèi)的緩存。

開啟二級緩存需要幾個步驟:

1、 MyBatis 中開啟緩存需要首先在設(shè)置中開啟 cacheEnabled

<settings>
    <setting name="cacheEnabled" value="true"/>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

cacheEnabled 默認(rèn)也是開啟狀態(tài)。

2、 在 mapper.xml 中使用二級緩存

在 UserMapper.xml 文件的 mapper 節(jié)點下增加一行 , 這個 mapper 就開啟了二級緩存。

MyBatis 緩存要求對應(yīng)的對象需要實現(xiàn)序列話,因此給 User 對象加上序列化

import java.io.Serializable;
public class User implements Serializable{
    private static final long serialVersionUID = 1L;
    private int id;
    private String name;
    public User(){}
    public User(int id,String name){
        this.id=id;
        this.name=name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    @Override
    public String toString() {
        return "id:"+this.id+" name:"+this.name;
    }
}

編寫測試用例,下面這段代碼在第一次查詢結(jié)束后關(guān)閉了 SqlSession,接著重新生成一個 SqlSession 執(zhí)行第二次查詢,一級緩存就沒有用了,這樣的場景下就需要二級緩存。

public class CacheTest3 {
    public static void main(String[] args) {
        // 獲取SqlSession
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        // 執(zhí)行Sql
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user=mapper.getUserById(1);
        System.out.println(user);
        // 第一次查詢結(jié)束后關(guān)閉 SqlSession
        sqlSession.close();
        sqlSession = MyBatisUtils.getSqlSession();
        // 執(zhí)行Sql
        mapper = sqlSession.getMapper(UserMapper.class);
        //同樣的條件查詢第二次
        User user2=mapper.getUserById(1);
        System.out.println(user2);
        sqlSession.close();
    }
}

使用 useCache 對具體某一個查詢設(shè)置不適用緩存:

<select id="getUserById" resultMap="UserMap" parameterType="int" useCache="false">
    select id,name from user where id=#{id};
</select>

cache 標(biāo)簽可以通過配置進行修改:

<cache
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="false"/>

重點講一下清除策略(eviction):

  • LRU – 最近最少使用:移除最長時間不被使用的對象。
  • FIFO – 先進先出:按對象進入緩存的順序來移除它們。
  • SOFT – 軟引用:基于垃圾回收器狀態(tài)和軟引用規(guī)則移除對象。
  • WEAK – 弱引用:更積極地基于垃圾收集器狀態(tài)和弱引用規(guī)則移除對象。

這里主要了解 LRU 和 FIFO 即可,默認(rèn)的清除策略是 LRU。

其他幾個屬性的配置如下:

flushInterval(刷新間隔)屬性可以被設(shè)置為任意的正整數(shù),設(shè)置的值應(yīng)該是一個以毫秒為單位的合理時間量。 默認(rèn)情況是不設(shè)置,也就是沒有刷新間隔,緩存僅僅會在調(diào)用語句時刷新。

size(引用數(shù)目)屬性可以被設(shè)置為任意正整數(shù),要注意欲緩存對象的大小和運行環(huán)境中可用的內(nèi)存資源。默認(rèn)值是 1024。

readOnly(只讀)屬性可以被設(shè)置為 true 或 false,默認(rèn)為 false。只讀的緩存會給所有調(diào)用者返回緩存對象的相同實例, 因此這些對象不能被修改,這就提供了可觀的性能提升。而可讀寫的緩存會(通過序列化)返回緩存對象的拷貝,速度上會慢一些,但是更安全。

到此這篇關(guān)于MyBatis一級緩存與二級緩存原理與作用分析的文章就介紹到這了,更多相關(guān)Mybatis緩存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中Set集合轉(zhuǎn)為List集合常見的兩種方式

    Java中Set集合轉(zhuǎn)為List集合常見的兩種方式

    List是Java中比較常用的集合類,指一系列存儲數(shù)據(jù)的接口和類,可以解決復(fù)雜的數(shù)據(jù)存儲問題,這篇文章主要給大家介紹了關(guān)于Java中Set集合轉(zhuǎn)為List集合常見的兩種方式,需要的朋友可以參考下
    2023-12-12
  • 基于jenkins上配置Credentials的2種方式

    基于jenkins上配置Credentials的2種方式

    這篇文章主要介紹了基于jenkins上配置Credentials的2種方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Java中實現(xiàn)線程間通信的實例教程

    Java中實現(xiàn)線程間通信的實例教程

    線程通信的目標(biāo)是使線程間能夠互相發(fā)送信號,另一方面線程通信使線程能夠等待其他線程的信號,這篇文章主要給大家介紹了關(guān)于Java中實現(xiàn)線程間通信的相關(guān)資料,本文通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-09-09
  • java實現(xiàn)將數(shù)字轉(zhuǎn)換成人民幣大寫

    java實現(xiàn)將數(shù)字轉(zhuǎn)換成人民幣大寫

    前面給大家介紹過使用javascript,php,c#,python等語言實現(xiàn)人民幣大寫格式化,這篇文章主要介紹了java實現(xiàn)將數(shù)字轉(zhuǎn)換成人民幣大寫的代碼,非常的簡單實用,分享給大家,需要的朋友可以參考下
    2015-04-04
  • java調(diào)用chatgpt接口來實現(xiàn)專屬于自己的人工智能助手

    java調(diào)用chatgpt接口來實現(xiàn)專屬于自己的人工智能助手

    這篇文章主要介紹了用java來調(diào)用chatget的接口,實現(xiàn)自己的聊天機器人,對人工智能感興趣的小伙伴可以參考閱讀
    2023-03-03
  • SpringBoot整合阿里云視頻點播的過程詳解

    SpringBoot整合阿里云視頻點播的過程詳解

    視頻點播(ApsaraVideo for VoD)是集音視頻采集、編輯、上傳、自動化轉(zhuǎn)碼處理、媒體資源管理、分發(fā)加速于一體的一站式音視頻點播解決方案。這篇文章主要介紹了SpringBoot整合阿里云視頻點播的詳細過程,需要的朋友可以參考下
    2021-12-12
  • 分享5個Java接口性能提升的通用技巧

    分享5個Java接口性能提升的通用技巧

    作為后端開發(fā)人員,我們總是在編寫各種API。這些API在服務(wù)初期可能表現(xiàn)不錯,但隨著用戶數(shù)量的增長,一開始響應(yīng)很快的API越來越慢,這時候你就需要考慮如何優(yōu)化你的API性能了。在這篇文章中,我總結(jié)了一些行之有效的API性能優(yōu)化技巧,希望能給有需要的朋友一些幫助
    2023-01-01
  • Java中使用JavaMail多發(fā)郵件及郵件的驗證和附件實現(xiàn)

    Java中使用JavaMail多發(fā)郵件及郵件的驗證和附件實現(xiàn)

    這篇文章主要介紹了Java中使用Java Mail多發(fā)郵件及郵件的驗證和附件實現(xiàn),包括在郵件中加入圖片等功能的實現(xiàn)講解,需要的朋友可以參考下
    2016-02-02
  • java private關(guān)鍵字用法實例

    java private關(guān)鍵字用法實例

    這篇文章主要介紹了java private關(guān)鍵字用法實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • Java?WorkBook對Excel的基本操作方法

    Java?WorkBook對Excel的基本操作方法

    這篇文章主要介紹了Java?WorkBook對Excel的基本操作方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03

最新評論

安庆市| 靖安县| 永丰县| 交城县| 枞阳县| 崇州市| 天全县| 昌吉市| 石台县| 廉江市| 陇南市| 武隆县| 惠东县| 巩留县| 永仁县| 阳谷县| 仁化县| 富源县| 开远市| 郎溪县| 延安市| 巴东县| 吴川市| 化德县| 奉节县| 沁源县| 清远市| 陵川县| 布尔津县| 余庆县| 荣昌县| 财经| 巍山| 吉林省| 阳西县| 木里| 潜山县| 茶陵县| 屯留县| 博兴县| 襄樊市|