springboot快速啓動(十三)——整合cache緩存

一 、緩存
說到緩存就得提存儲
在這裏插入圖片描述
電腦存儲分爲主存和輔存 一般來說主存就是內存 輔存就是硬盤。雖然都可以存儲但是這兩者的讀寫速度可以說是雲泥之別。

內存速度
DDR3傳輸帶寬 :8.5 GB/s——14.9 G MB/s
硬盤速度(市面上的大部分機械+固態)
80M/s——3400M/s
可以看出 不管硬盤再快都不可能超過內存的速度 他們之間的差距可以達到上百倍 而我們通常數據庫操作都是在硬盤中,爲了獲取更快的速度我們用到了緩存

二、boot+mybatis結合Redis開啓二級緩存
原理:
從3.1開始,Spring引入了對Cache的支持。其使用方法和原理都類似於Spring對事務管理的支持。Spring Cache是作用在方法上的,其核心思想是這樣的:當我們在調用一個緩存方法時會把該方法參數和返回結果作爲一個鍵值對存放在緩存中,等到下次利用同樣的參數來調用該方法時將不再執行該方法,而是直接從緩存中獲取結果進行返回。所以在使用Spring Cache的時候我們要保證我們緩存的方法對於相同的方法參數要有相同的返回結果。

三:Spring緩存抽象
Spring從3.1開始定義了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口來統一不同的緩存技術;並支持使用JCache(JSR-107)註解簡化我們開發;

  • Cache接口爲緩存的組件規範定義,包含緩存的各種操作集合;
  • Cache接口下Spring提供了各種xxxCache的實現;如RedisCache,EhCacheCache
    ,ConcurrentMapCache等;
  • 每次調用需要緩存功能的方法時,Spring會檢查檢查指定參數的指定的目標方法是否已經被調用過;如果有就直接從緩存中獲取方法調用後的結果,如果沒有就調用方法並緩存結果後返回給用戶。下次調用直接從緩存中獲取。
  • 使用Spring緩存抽象時我們需要關注以下兩點;
    1、確定方法需要被緩存以及他們的緩存策略
    2、從緩存中讀取之前緩存存儲的數據

四:幾個重要概念&緩存註解

名稱 解釋

Cache 緩存接口,定義緩存操作。實現有:RedisCache、EhCacheCache、ConcurrentMapCache等
CacheManager 緩存管理器,管理各種緩存(cache)組件
@Cacheable 主要針對方法配置,能夠根據方法的請求參數對其進行緩存
@CacheEvict 清空緩存
@CachePut 保證方法被調用,又希望結果被緩存。與@Cacheable區別在於是否每次都調用方法,常用於更新
@EnableCaching 開啓基於註解的緩存
keyGenerator 緩存數據時key生成策略
serialize 緩存數據時value序列化策略
@CacheConfig 統一配置本類的緩存註解的屬性

@Cacheable/@CachePut/@CacheEvict 主要的參數

名稱 解釋
value  緩存的名稱,在 spring 配置文件中定義,必須指定至少一個例如:@Cacheable(value=”mycache”) 或者@Cacheable(value={”cache1”,”cache2”}
key  緩存的 key,可以爲空,如果指定要按照 SpEL 表達式編寫,如果不指定,則缺省按照方法的所有參數進行組合例如:@Cacheable(value=”testcache”,key=”#id”)
condition  緩存的條件,可以爲空,使用 SpEL 編寫,返回 true 或者 false,只有爲 true 才進行緩存/清除緩存例如:@Cacheable(value=”testcache”,condition=”#userName.length()>2”)
unless  否定緩存。當條件結果爲TRUE時,就不會緩存。@Cacheable(value=”testcache”,unless=”#userName.length()>2”)
allEntries(@CacheEvict )   是否清空所有緩存內容,缺省爲 false,如果指定爲 true,則方法調用後將立即清空所有緩存例如:@CachEvict(value=”testcache”,allEntries=true)
beforeInvocation(@CacheEvict)  是否在方法執行前就清空,缺省爲 false,如果指定爲 true,則在方法還沒有執行的時候就清空緩存,缺省情況下,如果方法執行拋出異常,則不會清空緩存例如:@CachEvict(value=”testcache”,beforeInvocation=true)

五:SpEL上下文數據
Spring Cache提供了一些供我們使用的SpEL上下文數據,下表直接摘自Spring官方文檔:

名稱 位置 描述
methodName root對象 當前被調用的方法名
method root對象 當前被調用的方法
target root對象 當前被調用的目標對象實例
targetClass root對象 當前被調用的目標對象的類
args root對象 當前被調用的方法的參數列表
caches root對象 當前方法調用使用的緩存列表
Argument Name 執行上下文 當前被調用的方法的參數,如findArtisan(Artisan artisan),可以通過#artsian.id獲得參數
result 執行上下文 方法執行後的返回值(僅當方法執行後的判斷有效,如 unless cacheEvict的beforeInvocation=false)

注意:
1.當我們要使用root對象的屬性作爲key時我們也可以將“#root”省略,因爲Spring默認使用的就是root對象的屬性。 如
@Cacheable(key = “targetClass + methodName +#p0”)
2.使用方法參數時我們可以直接使用“#參數名”或者“#p參數index”。 如:
@Cacheable(value=“users”, key="#id")
@Cacheable(value=“users”, key="#p0")

SpEL提供了多種運算符
類型 運算符
關係 <,>,<=,>=,==,!=,lt,gt,le,ge,eq,ne
算術 +,- ,* ,/,%,^
邏輯 &&,||,!,and,or,not,between,instanceof
條件 ?: (ternary),?: (elvis)
正則表達式 matches
其他類型 ?.,?[…],![…],1,$[…]
以上的知識點適合你遺忘的時候來查閱,下面正式進入學習!

六、快速部署

1、引入依賴

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

2、啓動類加 @EnableCaching //開啓緩存
在這裏插入圖片描述
3、開啓使用
在這裏插入圖片描述
@CacheConfig(cacheNames = {“myCache”})註解來統一指定value的值,這時可省略value,如果你在你的方法依舊寫上了value,那麼依然以方法的value值爲準。
注:cacheName 值是唯一的

當然你也可以每一個方法的上面添加value 屬性 規定緩存在哪

配置 @CacheConfig:
示例:

@CacheConfig(cacheNames = {"myCache"})
public class BotRelationServiceImpl implements BotRelationService {
    @Override
    @Cacheable(key = "targetClass + methodName +#p0")//此處沒寫value
    public List<BotRelation> findAllLimit(int num) {
        return botRelationRepository.findAllLimit(num);
    }
  
}

其他屬性

String[] cacheNames() default {}; //和value註解差不多,二選一
String keyGenerator() default ""; //key的生成器。key/keyGenerator二選一使用
String cacheManager() default ""; //指定緩存管理器
String cacheResolver() default ""; //或者指定獲取解析器
String condition() default ""; //條件符合則緩存
String unless() default ""; //條件符合則不緩存
boolean sync() default false; //是否使用異步模式

查詢/更新 @Cacheable:
示例:

 @Cacheable(value = "emp" ,key = "targetClass + methodName +#p0")
    public List<NewJob> queryAll(User uid) {
        return newJobDao.findAllByUid(uid);
    }

其他屬性

String keyGenerator() default "";  //key的生成器。key/keyGenerator二選一使用
String cacheManager() default "";  //指定緩存管理器
String cacheResolver() default ""; //或者指定獲取解析器

更新 @CachePut:
示例:

    @CachePut(value = "emp", key = "targetClass + #p0")
    public NewJob updata(NewJob job) {
        NewJob newJob = newJobDao.findAllById(job.getId());
        newJob.updata(job);
        return job;
    }

    @Cacheable(value = "emp", key = "targetClass +#p0")//清空緩存
    public NewJob save(NewJob job) {
        newJobDao.save(job);
        return job;
    }

其他屬性

 String[] cacheNames() default {}; //與value二選一
String keyGenerator() default "";  //key的生成器。key/keyGenerator二選一使用
String cacheManager() default "";  //指定緩存管理器
String cacheResolver() default ""; //或者指定獲取解析器
String condition() default ""; //條件符合則緩存
String unless() default ""; //條件符合則不緩存

清除 @CacheEvict:
示例:

//清除一條緩存,key爲要清空的數據
    @CacheEvict(value="emp",key="#id")
    public void delect(int id) {
        newJobDao.deleteAllById(id);
    }

    //方法調用後清空所有緩存
    @CacheEvict(value="accountCache",allEntries=true)
    public void delectAll() {
        newJobDao.deleteAll();
    }

    //方法調用前清空所有緩存
    @CacheEvict(value="accountCache",beforeInvocation=true)
    public void delectAll() {
        newJobDao.deleteAll();
    }

其他屬性

String[] cacheNames() default {}; //與value二選一
String keyGenerator() default "";  //key的生成器。key/keyGenerator二選一使用
String cacheManager() default "";  //指定緩存管理器
String cacheResolver() default ""; //或者指定獲取解析器
String condition() default ""; //條件符合則清空

組合 @Caching:
示例:

    @Caching(cacheable = {
            @Cacheable(value = "emp",key = "#p0"),
            ...
    },
    put = {
            @CachePut(value = "emp",key = "#p0"),
            ...
    },evict = {
            @CacheEvict(value = "emp",key = "#p0"),
            ....
    })
    public User save(User user) {
        ....
    }

如何解決boot cache 遺留的問題:https://blog.csdn.net/weixin_42083036/article/details/103389596


  1. ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章