Cómo utilizar SpringCache's Cacheable, CacheEvict, Cacheput, Caching

Para la declaración de caché, la abstracción de caché de Spring proporciona un conjunto de anotaciones de Java
@Cacheable: Activa la población de la caché: activa la operación para guardar datos en la caché
@CacheEvict: Activa el desalojo de la caché: activa la operación para eliminar datos de la caché
@CachePut: Actualizaciones el caché sin interferir con la ejecución del método: no afecta la ejecución del método actualizar el caché
@Caching: Reagrupa múltiples operaciones de caché para ser aplicadas en un método: combina las múltiples operaciones anteriores
@CacheConfig: Comparte algunas configuraciones comunes relacionadas con el caché a nivel de clase : a nivel de clase La misma configuración de caché compartida
1. Introducir maven

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
   <exclusions>
       <!-- Lettuce的bug导致netty堆外内存溢出 切换使用jedis-->
       <exclusion>
           <groupId>io.lettuce</groupId>
           <artifactId>lettuce-core</artifactId>
       </exclusion>
   </exclusions>
</dependency>
<!--       Lettuce的bug导致netty堆外内存溢出 切换使用jedis-->
<dependency>
   <groupId>redis.clients</groupId>
   <artifactId>jedis</artifactId>
</dependency>

<!--        整合SringCache 简化缓存开发-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

2. Agregue información de configuración en application.properties

#以下是整合Spring Cache 的相关配置
#配置缓存的类型 (最简化的配置)
spring.cache.type=redis

#指定缓存的名字
#spring.cache.cache-names=qq,

#指定缓存的存活时间 单位:ms
spring.cache.redis.time-to-live=3600000

#为了区分redis其他的东西
#如果指定了前缀,就用我们指定的前缀,如果没有就默认使用缓存的名字(分区名-value)作为前缀
#优先级高
#spring.cache.redis.key-prefix=CACHE_
#默认是使用前缀的
spring.cache.redis.use-key-prefix=true

#是否缓存空值 防止缓存穿透
spring.cache.redis.cache-null-values=true

3. Agregar clase de configuración

//绑定配置文件的配置
@EnableConfigurationProperties(CacheProperties.class)
//开启缓存功能
@EnableCaching
@Configuration
public class MyCacheConfig {
    
    

//    @Autowired
//    CacheProperties cacheProperties;

    /**
     * 没有用上配置文件中的东西
     * 1)、原来配置文件的绑定配置是这样子的
     *     @ConfigurationProperties(prefix = "spring.cache")
     *     public class CacheProperties {
     * 2)、要让他生效
     *      @EnableConfigurationProperties(CacheProperties.class)
     * @return
     */
    @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;
    }
}

4. Prueba de consulta de escritura: y configurada para evitar la penetración y el colapso de la caché

 /**
     * 1、每一个需要缓存的数据我们都需要指定放到那个名字的缓存【缓存分区的划分【按照业务类型划分】】
     * 2、@Cacheable({"category"})
     *      代表当前方法的结果需要缓存,如果缓存中有,方法不调用
     *      如果缓存中没有,调用方法,最后将方法的结果放入缓存
     * 3、默认行为:
     *      1、如果缓存中有,方法不用调用
     *      2、key默自动生成,缓存的名字:SimpleKey[](自动生成的key值)
     *      3、缓存中value的值,默认使用jdk序列化,将序列化后的数据存到redis
     *      3、默认的过期时间,-1
     *
     *    自定义操作
     *      1、指定缓存使用的key     key属性指定,接收一个SpEl
     *      2、指定缓存数据的存活时间  配置文件中修改ttl
     *      3、将数据保存为json格式
     * 4、Spring-Cache的不足:
     *      1、读模式:
     *          缓存穿透:查询一个null数据,解决 缓存空数据:ache-null-values=true
     *          缓存击穿:大量并发进来同时查询一个正好过期的数据,解决:加锁 ? 默认是无加锁
     *          缓存雪崩:大量的key同时过期,解决:加上随机时间,Spring-cache-redis-time-to-live
     *       2、写模式:(缓存与数据库库不一致)
     *          1、读写加锁
     *          2、引入canal,感知到MySQL的更新去更新数据库
     *          3、读多写多,直接去数据库查询就行
     *
     *    总结:
     *      常规数据(读多写少,即时性,一致性要求不高的数据)完全可以使用SpringCache 写模式( 只要缓存数据有过期时间就足够了)
     *
     *    特殊数据:特殊设计
     *      原理:
     *          CacheManager(RedisManager) -> Cache(RedisCache) ->Cache负责缓存的读写
     *    sync = true解决缓存击穿 默认是false      
     */
    @Cacheable(value = {
    
    "category"}, key = "#root.method.name", sync = true)
    @Override
    public List<CategoryEntity> getLevel1Catrgorys() {
    
    

        //测试spring cache
        System.out.println("public List<CategoryEntity> getLevel1Catrgorys() {....");
        //压力测试  数据库navicat增加了 parent_cid 为索引
//        long l = System.currentTimeMillis();
        List<CategoryEntity> categoryEntities = baseMapper.selectList(new QueryWrapper<CategoryEntity>().eq("parent_cid", 0));
//        System.out.println("消耗时间->:" + (System.currentTimeMillis()-l) + "ms");
        return categoryEntities;
//        return null;//测试缓存空值
    }

Inserte la descripción de la imagen aquí
¿Qué pasa si necesitamos borrar la caché cuando modificamos o borramos datos?
5. Escriba una prueba de eliminación de caché: elimine
todos los datos en la partición de categoría, y también puede usar las siguientes anotaciones para eliminar la caché

@Caching(evict = {
	           @CacheEvict(value = "category", key = "'getLevel1Catrgorys'"),
	           @CacheEvict(value = "category", key = "'getCatalogJson'")
	   })

Para eliminar varios valores almacenados en caché.

    //存储同一类型的数据,都可以指定成同一个分区 分区名默认就是缓存的前缀
    //失效模式 删除category区下【所有】的数据
    @CacheEvict(value = "category", allEntries = true)
    //同时进行多种缓存操作 组合删除
	//    @Caching(evict = {
    
    
	//            //失效模式:修改删除缓存
	//            @CacheEvict(value = "category", key = "'getLevel1Catrgorys'"),
	//            @CacheEvict(value = "category", key = "'getCatalogJson'")
	//    })
	    //双写模式 修改后再放入缓存
	//    @CachePut
    @Transactional
    //级联更新 所有数据
    @Override
    public void updateCascade(CategoryEntity category) {
    
    
        this.updateById(category);
        categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
        //同时修改缓存中的数据
        //redis.del(catalogJSON);等待下次主动查询进行更新
    }

Supongo que te gusta

Origin blog.csdn.net/u014496893/article/details/113860988
Recomendado
Clasificación