缓存:SpringCache,@CacheEvict,@CachePut


 对于redis缓存数据。之前分析的,读的话:先读缓存,没有就查库然后写入缓存。

写的话:写db后 缓存不一致了,两种策略,失效策略和双写策略。

失效策略就是说直接删掉缓存

双写,就相当于是重新写入缓存,也可以说是更新缓存了吧。

正好这两种策略,对应 @CacheEvict,@CachePut

=======================================

CacheEvict的使用:

   /**
     * 级联更新所有关联的数据
     *
     * @param category
     */
    @CacheEvict(value = "category",key = "'getLevel1Categorys'") //注意要加单引号
    @Transactional
    @Override
    public void updateCascade(CategoryEntity category) {
        this.updateById(category);
        categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
    }
 @Cacheable(value = {"category"}, key = "#root.method.name", sync = true)
@Override
public List getLevel1Categorys() {
return baseMapper.selectList(new QueryWrapper().eq("cat_level", 1));
// 测试能否缓存null值
// return null;
}
 

上面加单引号,是因为这里是spel表达式。

测试:首先访问上面代码中下面的一个方法,查看redis是否有新的缓存,检查确实有:

 这里可以看到,之前的cacheable注解的value的值,就相当于给缓存进行分区,分的区名字就是category,然后这个区里面就有一个k v数据。

然后访问上面 一个方法,查看缓存是否删除了:

可以看到成功的删除了,注解的方式确实方便了许多!

==========================

改进之前的方法:

   /**
     * 用springCache来操作缓存
     *
     * @return
     */
    @Cacheable(value = {"category"}, key = "#root.methodName")
    @Override
    public Map> getCatelogJson() {

        Map> catalogJsonFromDb =getCatalogJsonFromDbWithRedisLock();
    return catalogJsonFromDb;
}

直接差数据库,还是都走分布式锁。

然后更新的代码也要改,这时候更新的话,就要删除这两个缓存了:

  /**
     * 级联更新所有关联的数据
     *
     * @param category
     */
    @Caching(
            evict = {
                    @CacheEvict(value = "category", key = "'getLevel1Categorys'"), //注意要加单引号
                    @CacheEvict(value = "category", key = "'getCatelogJson'")
            }
    )
    @Transactional
    @Override
    public void updateCascade(CategoryEntity category) {
        this.updateById(category);
        categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
    }

或者用 

@CacheEvict(value = "category",allEntries = true)  
这种方式,他就会删除这个 category分区下面的所有数据。

 在redis中,分区的话,就是这个样子的: