缓存: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中,分区的话,就是这个样子的: