qinfengge

qinfengge

醉后不知天在水,满船清梦压星河
github
email
telegram

spring boot中的快取

緩存通常用來加快資料庫中經常要使用的資料。大部分情況下我們使用 redis 來緩存 MySQL 資料庫的熱點資料。

啟用緩存#

在 spring boot 中使用緩存還是比較簡單的
首先添加依賴

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

在啟動類開啟緩存支持

@SpringBootApplication
@EnableCaching

在配置文件中指定使用 redis 緩存,如果不指定則使用 jvm 內存
在使用 redis 做緩存之前,需要正確的配置 redis 的連接信息

#cacheing
spring.cache.type=redis
#指定前綴
#spring.cache.redis.key-prefix=test
#指定存活時長
#spring.cache.redis.time-to-live= 1d

最後在 redis 的配置類中增加 @EnableCaching 註解和 緩存管理器

/**
     * 申明緩存管理器,會創建一個切面(aspect)並觸發Spring緩存註解的切點(pointcut)
     * 根據類或者方法所使用的註解以及緩存的狀態,這個切面會從緩存中獲取資料,將資料添加到緩存之中或者從緩存中移除某個值
     *
     * @return
     */
    @Bean
    @SuppressWarnings("all")
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //解決查詢緩存轉換異常的問題
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        // 配置序列化(解決亂碼的問題)
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofDays(1))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();

        return RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
    }

緩存註解#

緩存註解解釋
@EnableCaching開啟緩存註解的支持
@CacheConfig用於統一制定一些配置參數,這樣在其他緩存註解裡面就不用重複指定
@Cacheable如果之前已經有緩存資料值直接返回緩存資料,否則執行方法,緩存方法的返回結果
@CachePut能夠根據方法的請求參數對其結果進行緩存,和 @Cacheable 不同的是,它每次都會觸發真實方法的調用
@CacheEvict能夠根據一定的條件對緩存進行清空
@Caching組合多個 Cache 註解的使用

@CacheConfig#

此註解常用來配置統一的緩存參數

// 在controller中使用此註解用來指定緩存的名字,類似於前綴
@CacheConfig(cacheNames = "test")

@Cacheable#

此註解常用於查詢方法中,使用此註解後會先從緩存中查,如果緩存中沒有,再從資料庫中查,並把查詢出的結果放入緩存中。

Mermaid Loading...

image

// 如果配置了@CacheConfig的全局cacheName/value 則這裡面的可以省略
@Cacheable(value = "test", key = "methodName")
// @Cacheable支持el表達式
@Cacheable(key = "methodName + ':' + #p0 + ':' + #p1")
public Result<Object> getSubordinateAddress(String province,String city){}
@Cacheable(value="users", key="#user.id")
public User find(User user) {}

key 支持的屬性列表如下

屬性名稱描述示例
methodName當前方法名#root.methodName
method當前方法#root.method.name
target當前被調用的對象#root.target
targetClass當前被調用的對象的 class#root.targetClass
args當前方法參數組成的數組#root.args[0]
caches當前被調用的方法使用的 Cache#root.caches[0].name

@CachePut#

此註解常用來更新緩存。它會忽略緩存中的值,而是始終執行方法。
執行順序為 調用方法 ---> 獲取結果 ---> 更新緩存

Mermaid Loading...
@CachePut(value = "myCache", key = "#entity.id")
    public void saveEntity(MyEntity entity) {
        repository.save(entity);
    }

@CacheEvict#

此註解用來刪除對應的緩存。

image

@CacheEvict(value = "myCache", key = "#id")
    public void deleteEntityById(Long id) {
        repository.deleteById(id);
    }

在使用 allEntries=true 時,會忽略 key,刪除指定 cacheName/value 中的全部值。
你也可以使用 cacheMange 對象來刪除指定的緩存,以下代碼表示當 test 緩存不為空時,將其清空

Objects.requireNonNull(restTemplateConfig.cacheManager(null).getCache("test")).clear();

@Caching#

此註解用來組合多個上面的緩存註解進行使用

image

@Caching(
        cacheable = {
            @Cacheable(value = "myCache", key = "#id")
        },
        evict = {
            @CacheEvict(value = "otherCache", key = "#id")
        }
    )
    public MyEntity getEntityById(Long id) {
        return repository.findById(id).orElse(null);
    }

調用順序如下

Mermaid Loading...

SpringBoot 專案中使用緩存 Cache 的正確姿勢!!!
SpringBoot 緩存管理 @EnableCaching、@Cacheable

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。