(5)@CacheEvict注解
(a)修改 application.properties 文件,使用分区的前缀
spring.cache.type=redisspring.cache.redis.time-to-live=3600000#如果指定了前缀就用我们指定的前缀,如果没有就默认使用缓存的名字作为前缀#spring.cache.redis.key-prefix=CACHE_spring.cache.redis.use-key-prefix=true#是否缓存空值 防止缓存穿透spring.cache.redis.cache-null-values=true (b)修改 com.atguigu.gulimall.product.service.impl.CategoryServiceImpl 的 updateCascade 方法
/** * 级联更新所有关联的数据 * @CacheEvict:失效模式 * @param category */ @CacheEvict(value = "category", key = "'getLevel1Catagories'") //category:key @Override @Transactional public void updateCascade(CategoryEntity category) { this.updateById(category); categoryBrandRelationService.updateCategory(category.getCatId(), category.getName()); //同时修改缓存中的数据 //redis.del("catalogJson");等待下次主动查询进行更新 } 测试: 访问 http://localhost:10000,redis中结果如下:
启动网关、启动renren-fast,修改分类,redis中结果:
思考:如果修改分类要清除多个缓存呢,例如修改分类,需要删除一级、二级和三级缓存
(c)先来修改之前的 getCatalogJson 方法,获取分类的json数据,使用@Cacheable注解缓存数据
@Cacheable(value = "category", key = "#root.methodName")@Overridepublic Map
可以看到,多次访问后,一级分类菜单和分类的json数据都只访问了一次数据库,查看redis情况
可以看到,redis中有两个key,一个是一级分类,一个是分类的json数据,并且key的前缀都是 “category”,后缀是方法名
思考:现在我们从管理后台修改分类,如何一次性是这两个key都失效呢
(d)修改 com.atguigu.gulimall.product.service.impl.CategoryServiceImpl 的 updateCascade 方法
使用 @Caching 注解,里面存储数组对象,指定多个删除的key值
/** * 级联更新所有关联的数据 * @CacheEvict:失效模式 * 1、同时进行多种缓存操作 @Caching * @param category *///@CacheEvict(value = "category", key = "'getLevel1Catagories'")@Caching(evict = { @CacheEvict(value = "category", key = "'getLevel1Catagories'"), @CacheEvict(value = "category", key = "'getCatalogJson'")})//category:key@Override@Transactionalpublic void updateCascade(CategoryEntity category) { this.updateById(category); categoryBrandRelationService.updateCategory(category.getCatId(), category.getName()); //同时修改缓存中的数据 //redis.del("catalogJson");等待下次主动查询进行更新} 测试: 访问 gulimall.com,然后后台修改分类,发现两个key都被删除了,这里就不再截图展示了 思考:这样一个一个指定过于麻烦,我们如何一次性操作简便呢(e)修改 com.atguigu.gulimall.product.service.impl.CategoryServiceImpl 的 updateCascade 方法
使用 @CacheEvict(value = "category", allEntries = true),直接一次性删除分区 “category”里面的数据
/** * 级联更新所有关联的数据 * @CacheEvict:失效模式 * 1、同时进行多种缓存操作 @Caching * 2、指定删除某个分区下的所有数据 @CacheEvict(value = "category", allEntries = true) * 3、存储同一类型的数据,都可以指定成同一个分区。分区名默认就是缓存的前缀 * @param category */ //@CacheEvict(value = "category", key = "'getLevel1Catagories'")// @Caching(evict = {// @CacheEvict(value = "category", key = "'getLevel1Catagories'"),// @CacheEvict(value = "category", key = "'getCatalogJson'")// }) //category:key @CacheEvict(value = "category", allEntries = true) @Override @Transactional public void updateCascade(CategoryEntity category) { this.updateById(category); categoryBrandRelationService.updateCategory(category.getCatId(), category.getName()); //同时修改缓存中的数据 //redis.del("catalogJson");等待下次主动查询进行更新 }