zoukankan      html  css  js  c++  java
  • SpringCache

    Spring 3.1 开始  官方文档:https://docs.spring.io/spring-framework/docs/5.1.18.RELEASE/spring-framework-reference/integration.html#cache

    Cache & CacheManager

    SpringCache整合,简化缓存开发

    1. 引入依赖  spring-boot-starter-cache、spring-boot-starter-data-redis
    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-cache -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

      2.自动配置

       CacheAutoConfiguration会导入 RedisCacheConfiguration

       自动配好了缓存管理器RedismanagerCache

      3.手动配置

    spring.cache.type=redis

      4.测试使用

      @Cacheable  : 触发将数据保存到缓存的操作

      @CacheEvict : 触发将数据从缓存中删除的操作

      @CachePut :  不影响方法执行,更新缓存

      @Caching :  组合以上多个操作

      @CacheConfig :在类级别共享缓存的相同配置

    1. 开启缓存功能@Enablecaching
    2. 方法上添加@Cacheable    如果缓存中有,方法不用调用。如果缓存中没有,会调用方法,最后将方法的结果放入缓存

        【缓存的分区(按照业务类型分)】 @Cacheable("category")

       3.默认行为:

    • 如果缓存中有,方法不会调用
    • key默认自动生成,缓存的名字::Simplekey[]{自动生成key值}
    • 缓存的value值,默认使用jdk序列化机制,将序列化后的数据存到redis
    • 默认ttl时间:-1

      4.自定义行为

    • 指定生成的缓存使用的key,key属性制定,接收一个Spel
    • 指定缓存的存活时间,配置文件中修改
    • 将数据保存为json模式

      

    自定义配置

    spring.cache.redis.time-to-live=300000
    spring.cache.type=redis
    
    spring.cache.redis.key-prefix=CACHE_
    spring.cache.redis.use-key-prefix=true
    #是否缓存空值,防止缓存穿透
    spring.cache.redis.cache-null-values=true
    @EnableConfigurationProperties(CacheProperties.class)
    @Configuration
    @EnableCaching
    public class MyCacheConfig {
        @Bean
        RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties){
            RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
            //config = config.entryTtl();
            config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
            config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
    
            CacheProperties.Redis redisProperties = cacheProperties.getRedis();
            //将配置文件中所有的配置都生效
            if (redisProperties.getTimeToLive() != null) {
                config = config.entryTtl(redisProperties.getTimeToLive());
            }
            if (redisProperties.getKeyPrefix() != null) {
                config = config.prefixKeysWith(redisProperties.getKeyPrefix());
            }
            if (!redisProperties.isCacheNullValues()) {
                config = config.disableCachingNullValues();
            }
            if (!redisProperties.isUseKeyPrefix()) {
                config = config.disableKeyPrefix();
            }
    
            return config;
        }
    }

    Spring Cache使用

    @Cacheable  触发缓存写   (value=catagory:缓存分区,key=缓存后缀)

      @Cacheable(value = {"catagory"},key = "#root.method.name")
        @Override
        public List<CategoryEntity> getLevel1Categorys() {
            List<CategoryEntity> list = baseMapper.selectList(new QueryWrapper<CategoryEntity>().eq("parent_cid", 0));
            return list;
        }

    @CacheEvict 缓存删

      /**
         * 级联更新所有关联操作
         * @CacheEvict:失效模式
         * 同时进行多种缓存操作
         * @param category
         */
    //    @Caching(evict = {
    //            @CacheEvict(value = "category",key = "'getLevel1Categorys'"),
    //            @CacheEvict(value = "category",key = "'getCatalogJson'")
    //    })
    
        /**
         *指定某分区(category)下的所有数据,全部删除。
         */
        @CacheEvict(value = "category",allEntries = true)
        @Transactional
        @Override
        public void updateCascade(CategoryEntity category) {

    Spring-cache不足

      1、读模式

    • 缓存穿透:查询一个null数据。解决:缓存空数据;
    #是否缓存空值,防止缓存穿透
    spring.cache.redis.cache-null-values=true
    • 缓存击穿:大量并发进来同时查询一个正好过期的数据。(默认不加锁)解决:加锁  sync=true(加锁)
    @Cacheable(value = {"catagory"},key = "#root.method.name",sync = true)
    • 缓存雪崩:大量key同时过期(超大应用存在考虑)。解决:加随机时间。加上过期时间

       2、写模式(缓存与数据库一致)

    • 读写加锁
    • 引入Cane了,感知到mysql的更新去更新数据库
    • 读多写多,直接去数据库查询

      3、原理

       使用整合redis

       CacheManager(RedisCacheManager) -> Cache(RedisCache)

    总结:

      常规数据(读多写少,及时性一致性要求不高的数据);完全可以使用Spring-Cache;写模式( 只要有过期时间即可

      特殊数据:特殊设计

  • 相关阅读:
    【bzoj1878】[SDOI2009]HH的项链
    【bzoj2821】作诗(Poetize)
    【bzoj2120】数颜色
    PAT 乙级真题 1005.德才论
    PAT 乙级真题 1004.福尔摩斯的约会
    博客园使用悬挂猫(上吊猫)置顶插件
    PAT 乙级真题 1002.数字分类
    AcWing 789.数的范围
    AcWing 788.逆序对的数量
    二分查找
  • 原文地址:https://www.cnblogs.com/sgrslimJ/p/13723571.html
Copyright © 2011-2022 走看看