整合 Spring Cache

  接下来使用Spring提供的缓存技术来实现Redis缓存的使用,在使用之前,需要了解缓存的两种模式:读模式写模式
  读模式就是如何去读取一个数据,需要遵循现从缓存中读取,如果缓存中没有在去数据库中查询,查到数据就放到缓存中方便下一次使用;
  写模式就是往缓存中存数据,但是写模式需要保持缓存和数据库数据的一致性,可以使用双写模式失效模式
  双写模式就是当我们修改了数据库中的某个数据时,将修改后的数据更新到缓存中,将旧的数据覆盖掉
  失效模式同样的当修改了一个数据,我们就直接将当前数据所在的缓存之前全部清除掉,下一次查询时直接去数据库查询最新的数据
  当然,在之前的使用,这些代码都是重复的,所以Spring专门抽取了一个针对的缓存的抽象层:Spring Cache;Spring从3.1开始定义了org. springframework.cache.Cache和org. springframework.cache.CacheManager接口来统一不同的缓存技术,并且支持JCache注解简化开发,相关操作可以参考官方文档(传送门)
  接下来就开始使用Sring Cache

  1. 导入jar包,注意需要使用哪种作为缓存就导入它,例如我用redis为例

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

  2. 编写配置,因为我使用的是Redis缓存,需要先配置Redis相关的

spring:
  redis:
    host: 192.168.0.109
  cache:
    type: redis # 指定缓存的类型
    redis:
      time-to-live: 3600000 # 过期时间,单位毫秒
      key-prefix: cache_ # key的前缀
      use-key-prefix: true # 是否使用前缀
      cache-null-values: true # 是否缓存空值,防止缓存穿透

  3. 先了解哈Cache的注解

  • @Cacheable:触发将数据保存到缓存的操作
  • @CacheEvict:触发将数据从缓存中删除的操作
  • @CachePut:在不影响方法的执行的情况下更新缓存
  • @Caching:组合多个缓存的操作
  • @CacheConfig:在类级别共享缓存的相同配置

  4. 自定义缓存配置类,并通过 @EnableCaching 注解开启缓存

import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@EnableCaching // 开启缓存
@Configuration
@EnableConfigurationProperties(CacheProperties.class)//绑定属性配置
public class MyCacheConfig {
    
    

    @Bean
    public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
    
    
        CacheProperties.Redis redisProperties = cacheProperties.getRedis();
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        //key的序列化方式
        config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
        //value的序列化方式
        config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericFastJsonRedisSerializer()));
        //过期时间
        if (redisProperties.getTimeToLive() != null) {
    
    
            config = config.entryTtl(redisProperties.getTimeToLive());
        }
        //key前缀
        if (redisProperties.getKeyPrefix() != null) {
    
    
            config = config.prefixCacheNameWith(redisProperties.getKeyPrefix());
        }
        //是否缓存空值
        if (!redisProperties.isCacheNullValues()) {
    
    
            config = config.disableCachingNullValues();
        }
        //是否使用前缀
        if (!redisProperties.isUseKeyPrefix()) {
    
    
            config = config.disableKeyPrefix();
        }
        return config;
    }
}

  5. 开启测试,在测试中,第一次缓存中没有数据,执行了查询数据库,第二次缓存中有数据,直接返回了缓存中的数据而没有执行查询数据库

@Override
@Cacheable(value = RedisKeyUtils.catalogKey)//指定key
public List<CategoryEntity> getCatalogJsonWithRedisson() {
    
    
    List<CategoryEntity> categoryEntities = listWithTree();
    return categoryEntities;
}

猜你喜欢

转载自blog.csdn.net/weixin_45481406/article/details/113484554