09-SpringBoot的緩存-1

09-SpringBoot的緩存-1

本文初概的介紹了SpringBoot的緩存仆救,并介紹了EhCache的初級使用葫男。更多深入的用法,請其他查看專業(yè)文檔分苇。

目錄


image.png

1.什么是緩存

  • 一種以為鍵值對方式存在于內(nèi)存的數(shù)據(jù)。一旦數(shù)據(jù)被緩存屁桑,用戶的請求可不通過代碼邏輯快速提供數(shù)據(jù)反饋医寿。

  • 在鍵值對中,用LRU(last recently used)算法來保證對最近不常訪問的數(shù)據(jù)進行清除

  • 由于存在內(nèi)存中蘑斧,通常一斷電靖秩,緩存數(shù)據(jù)就Over了。

2.解決的問題

  • 提升性能

    主要用于讀多寫少的場景

  • 緩解數(shù)據(jù)庫壓力

    比如商城秒殺

3.使用緩存的場景

  • 數(shù)據(jù)實時性要求不高

  • 對性能要求比較高

4.SpringBoot中對緩存的支持

  • JCache

  • EhCache

  • Hazelcast

  • Infinispan

  • Couchbase

  • Redis

  • Caffeine

  • Simple

  • EhCache和Redis是目前比較主流的緩存使用方式

5. EhCache

單機竖瘾,配置簡單沟突,快速上手,單機上性能好(JVM操作)捕传。

劣勢:拓展性性能較差惠拭。在集群方案中,基本看不到應(yīng)用身影。

實現(xiàn)

本實現(xiàn)采用的SpringBoot版本信息如下:

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.M4</version>
<relativePath/>
</parent>

下面我們來一步一步實現(xiàn)职辅。

SpringBoot添加依賴

<dependencies>
    ……
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    <dependency>
        <groupId>net.sf.ehcache</groupId>
        <artifactId>ehcache</artifactId>
    </dependency>
</dependencies>

SpringBoot緩存配置

緩存配置一般放在resources目下棒呛,名為一個ehcache.xml文件,如果沒有域携,請自行創(chuàng)建簇秒。

修改配置文件位置

通常配置的位置在resouces目錄下,如果要修改秀鞭,請在application.properties中進行修改:

spring.cache.ehcache.config=classpath:config/another-config.xml
默認配置
    <defaultCache maxElementsInMemory="10000"
                   eternal="false"
                   timeToIdleSeconds="120"
                   timeToLiveSeconds="120"
                   overflowToDisk="false"
                   diskPersistent="false"
                   diskExpiryThreadIntervalSeconds="120"
    />

部分配置的說明:

? name 緩存名唯一標識
? maxElementsInMemory="1000" 內(nèi)存中最大緩存對象數(shù)
? eternal="false" 是否永久緩存
? timeToIdleSeconds="3600" 緩存清除時間 默認是0 即永不過期
? timeToLiveSeconds="0" 緩存存活時間 默認是0 即永不過期
? overflowToDisk="true" 緩存對象達到最大數(shù)后趋观,將其寫入硬盤
? maxElementsOnDisk="10000" 磁盤最大緩存數(shù)
? diskPersistent="false" 磁盤持久化
? diskExpiryThreadIntervalSeconds="120" 磁盤緩存的清理線程運行間隔
? memoryStoreEvictionPolicy="FIFO" 緩存清空策略
? FIFO 先進先出
? LFU less frequently used 最少使用
? LRU least recently used 最近最少使用

自定義配置

在這里定義一個DiskCache,代表緩存會存儲在磁盤中:

    <cache name="DiskCache"
           maxEntriesLocalHeap="10000"
           eternal="true"
           timeToIdleSeconds="120"
           timeToLiveSeconds="120"
           overflowToDisk="true"
           diskPersistent="true"
           diskExpiryThreadIntervalSeconds="120">
    </cache>

配置的全貌為:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<diskStore path="java.io.tmpdir/cache"/>
    <!--默認緩存設(shè)置-->
    <defaultCache maxElementsInMemory="10000"
                   eternal="false"
                   timeToIdleSeconds="120"
                   timeToLiveSeconds="120"
                   overflowToDisk="false"
                   diskPersistent="false"
                   diskExpiryThreadIntervalSeconds="120"
    />
     
    <cache name="DiskCache"
           maxEntriesLocalHeap="10000"
           eternal="true"
           timeToIdleSeconds="120"
           timeToLiveSeconds="120"
           overflowToDisk="true"
           diskPersistent="true"
           diskExpiryThreadIntervalSeconds="120">
    </cache>
</ehcache>

SpringBoot緩存啟動定義

重在@EnableCaching標簽

@SpringBootApplication
@EnableCaching
public class Demo1Application {
    public static void main(String[] args) {
        SpringApplication.run(Demo1Application.class, args);
    }
}

SpringBoot緩存功能實現(xiàn)

Dao實現(xiàn)

我們先來普及一下幾個注解锋边,如下:

@CacheConfig

在Dao類中進行聲明皱坛,如果需要進行自定義類聲明,需要配合CacheNames

@Cacheable

使用在方法的定義宠默,標明是緩存方法麸恍,使用在查詢方法上。

@CachePut

在使用update搀矫,以及insert方法的時候抹沪,需要使用這個注解,同時需要聲明key瓤球,它代表了update的時候融欧,key是使用哪一個(SQL上的術(shù)語)。

一般這么寫@CachePut(key = "book.id")卦羡,book是方法入?yún)⒌膮?shù)噪馏,在Update的時候,通常使用的是一個對象對吧绿饵。

這里有一個點需要注意欠肾,在定義@CachePut方法的時候,一定要將save對象返回拟赊,也就是方法return save對象刺桃,否則在后續(xù)get的時候,可能出現(xiàn)對象獲取null的情況吸祟!切記切記瑟慈。

@CacheEvict

在刪除的時候使用,依然需要聲明key屋匕,一般這樣聲明@CacheEvict(key = "#id")葛碧,id為我們需要刪除對象的主鍵,也是我們刪除方法的入?yún)ⅰ?/p>

最后过吻,來一個整體示例:

import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Repository;

import com.example.demo.beans.Book;

@Repository
@CacheConfig(cacheNames = "DiskCache")
public class BookDao {
    private Book mBook;
    /**
     *  初始化Book對象进泼。方便做test
     * @return
     */
    public Book initBookCache() {
        mBook = new Book();
        mBook.setId(1);
        mBook.setName("西游記");
        mBook.setAuthor("羅貫中");
        return mBook;
    }
    
        
    @Cacheable
    public Book getBookById(Integer id) {
        System.out.println("getBookById:未使用緩存");
        if(id.equals(mBook.getId())) { // 模擬數(shù)據(jù)庫查詢
            return mBook;
        }
        return null;
    }
        
    @CachePut(key = "#mBook.id")
    public Book updateBookById(Book mBook) {
        System.out.println("updateBook:未使用緩存");
        this.mBook = mBook;  // 模擬數(shù)據(jù)庫存儲
        return mBook; // 請注意,這里一定要返回!否則緩存數(shù)據(jù)不會更新T道拧U扯肌!K⑴邸翩隧!
    }
    
    @CacheEvict(key = "#id")
    public void deleteBookById(Integer id) {
        System.out.println("deleteBookById:未使用緩存");
        // 這里執(zhí)行刪除操作,同時使用@CacheEvict呻纹,將會把緩存中的數(shù)據(jù)也清除堆生。
        // 刪除后,調(diào)用getBookById雷酪,不會使用緩存淑仆。
    }

}
Bean實現(xiàn)

實現(xiàn)接口Serializabe

import java.io.Serializable;

public class Book implements Serializable{
        
    private static final long serialVersionUID = 1L;
    
    private Integer id;
    private String name;
    private String author;
    
    // ……getter/setter
}

SpringBoot測試

使用通常的測試即可,有如下注解需要了解

@RunWith(SpringRunner.class)

@Spring BootTest

@Autowired

@Test

@Before哥力,@BeforeClass蔗怠,@After,@AfterClass吩跋,@Igonore寞射,都可以使用

在代碼中,如果使用了緩存锌钮,是不會進入方法的桥温,所以我們需要結(jié)合打印來理解。部分注釋已經(jīng)寫在代碼上了梁丘。

package com.example.demo;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import com.example.demo.beans.Book;
import com.example.demo.services.BookDao;

import static org.hamcrest.CoreMatchers.containsString;

import org.junit.Assert;

@RunWith(SpringRunner.class)
@SpringBootTest
public class CacheTest {

    @Autowired
    BookDao mBookDao;

    @Test
    public void contextLoads() {
        mBookDao.initBookCache();

        // 查詢測試
        mBookDao.getBookById(1); // 方法打印
        mBookDao.getBookById(1); // 使用緩存:不應(yīng)打印

        // 刪除測試
        mBookDao.deleteBookById(1); // 方法打印
        Book mBook = mBookDao.getBookById(1); // 若已經(jīng)刪除侵浸,這里再獲取,應(yīng)該打印未使用緩存

        // 升級測試
        Book mBook1 = new Book();
        mBook1.setId(1);
        mBook1.setName("西游記2");
        mBook1.setAuthor("羅貫中");
        mBookDao.updateBookById(mBook1);// 打印update
        mBook = mBookDao.getBookById(1); // 不應(yīng)打印
        System.out.println(mBook.toString()); // 看到升級項
        Assert.assertThat(mBook.toString(),containsString("西游記2"));

        // insert測試
        mBook = mBookDao.getBookById(1);
        mBook.setId(10);
        mBookDao.updateBookById(mBook);
        mBook = mBookDao.getBookById(10); // 應(yīng)打印
        System.out.println(mBook.toString()); 
        Assert.assertThat(mBook.toString(), containsString("id:10"));
    }
}

問題:

Eclipse中出現(xiàn)問題:no tests found with test runner 'JUnit 5'

解決:

問題在Eclipse中出現(xiàn)氛谜,問題在于需要解決JUnit5切換為4掏觉。解決辦法是:在對應(yīng)的項目,右鍵->Run Configurations 值漫,左面選擇JUnit履腋,右面就會看到有個Test runner的選項,選擇JUnit4惭嚣。

提示不推薦使用Assert類型

解決:把import junit.framework.TestCase;的引入,改為import org.junit.Assert;

引用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市谋国,隨后出現(xiàn)的幾起案子槽地,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捌蚊,死亡現(xiàn)場離奇詭異集畅,居然都是意外死亡,警方通過查閱死者的電腦和手機缅糟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門挺智,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人窗宦,你說我怎么就攤上這事赦颇。” “怎么了赴涵?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵媒怯,是天一觀的道長。 經(jīng)常有香客問我髓窜,道長扇苞,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任寄纵,我火速辦了婚禮鳖敷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘擂啥。我一直安慰自己哄陶,他們只是感情好,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布哺壶。 她就那樣靜靜地躺著屋吨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪山宾。 梳的紋絲不亂的頭發(fā)上至扰,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機與錄音资锰,去河邊找鬼敢课。 笑死,一個胖子當著我的面吹牛绷杜,可吹牛的內(nèi)容都是我干的直秆。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼鞭盟,長吁一口氣:“原來是場噩夢啊……” “哼圾结!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起齿诉,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤筝野,失蹤者是張志新(化名)和其女友劉穎晌姚,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體歇竟,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡挥唠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了焕议。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宝磨。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖号坡,靈堂內(nèi)的尸體忽然破棺而出懊烤,到底是詐尸還是另有隱情,我是刑警寧澤宽堆,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布腌紧,位于F島的核電站,受9級特大地震影響畜隶,放射性物質(zhì)發(fā)生泄漏壁肋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一籽慢、第九天 我趴在偏房一處隱蔽的房頂上張望浸遗。 院中可真熱鬧,春花似錦箱亿、人聲如沸跛锌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽髓帽。三九已至,卻和暖如春脑豹,著一層夾襖步出監(jiān)牢的瞬間郑藏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工瘩欺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留必盖,地道東北人。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓俱饿,卻偏偏與公主長得像歌粥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拍埠,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容

  • Ehcache是現(xiàn)在最流行的純Java開源緩存框架阁吝,配置簡單、結(jié)構(gòu)清晰械拍、功能強大突勇,最初知道它,是從Hibernat...
    安易學(xué)車閱讀 2,030評論 0 11
  • ---------------------------------------------------------...
    LAMYMAY閱讀 735評論 0 3
  • 具體在Springboot中使用緩存如下: 1.在pom.xml中引入cache依賴坷虑,添加如下內(nèi)容: 2.在Spr...
    crMiao閱讀 5,169評論 0 4
  • 一甲馋、簡介 Ehcache是一個用Java實現(xiàn)的使用簡單,高速迄损,實現(xiàn)線程安全的緩存管理類庫定躏,ehcache提供了用內(nèi)...
    小程故事多閱讀 43,824評論 9 59
  • 昨晚我買了一本詩集 丟了一臺Kindle 我常常在自己身上 施展這種極其無趣的幽默感 既不好笑也不悲傷 如今我對失...
    浪蕩馬閱讀 165評論 0 0