谷粒商城SpringCache缓存(二十九)

167、缓存-SpringCache-简介-172、缓存-SpringCache-原理与不足

 感觉也比较简单,视频中也是跟着官网的介绍做的,可以参考前面一篇的中文翻译。

主要代码如下:

/**
     * 级联更新所有关联的数据
     * @param category
     */
    @Transactional
    @Override
//    @Caching( evict ={
//            @CacheEvict(value={"category"},key = "'getLevel1Categorys'"),
//            @CacheEvict(value={"category"},key = "'getCatalogJson''")
//    })
    @CacheEvict(value ="category",allEntries = true)
    public void updateCascade(CategoryEntity category) {
        this.updateById(category);
        categoryBrandRelationService.updateCategory(category.getCatId(),category.getName());
    }

    /**
     * 查询所有一级分类
     *
     * @return
     */
   // @Cacheable(value={"category"},key = "'level1Categorys'")
    //代表当前结果需要缓存,如果有就不需要缓存,没有则缓存
    @Cacheable(value={"category"},key = "#root.method.name")
    @Override
    public List<CategoryEntity> getLevel1Categorys() {
        List<CategoryEntity> categoryEntities = baseMapper.selectList(new QueryWrapper<CategoryEntity>().eq("parent_cid", 0));
        return categoryEntities;
    }

    public Boolean lock(String key, String value,String luaPath) throws IOException {
        DefaultRedisScript<Boolean> lockScript = new DefaultRedisScript<>();
        ClassPathResource resource = new ClassPathResource(luaPath);
        ResourceScriptSource source = new ResourceScriptSource(resource);
        lockScript.setScriptSource(source);
        lockScript.setResultType(Boolean.class);
        Boolean result = (Boolean) stringRedisTemplate.execute(lockScript, Arrays.asList(key, value));
        return result;
    }


    @Override
    @Cacheable(value={"category"},key = "#root.method.name")
    public Map<String, List<Catalog2Vo>> getCatalogJson() {
        //查询出所有分类
        List<CategoryEntity> selectList = baseMapper.selectList(null);
        //先查出所有一级分类
        List<CategoryEntity> level1Categorys = getCategorys(selectList, 0L);
        //封装数据 map k,v 结构
        Map<String, List<Catalog2Vo>> map = level1Categorys.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {
            //每一个的一级分类,查到这个一级分类的二级分类
            List<CategoryEntity> category2Entities = getCategorys(selectList, v.getCatId());
            List<Catalog2Vo> catelog2Vos = null;

            if (category2Entities != null) {
                catelog2Vos = category2Entities.stream().map(level2 -> {
                    //封装catalog2Vo
                    Catalog2Vo catalog2Vo = new Catalog2Vo(v.getCatId().toString(), null, level2.getCatId().toString(), level2.getName());
                    //每一个二级分类,查到三级分类
                    List<CategoryEntity> category3Entities = getCategorys(selectList, level2.getCatId());
                    if (category3Entities != null) {
                        List<Object> catalog3List = category3Entities.stream().map(level3 -> {
                            //封装catalog3Vo
                            Catalog2Vo.Catalog3Vo catalog3Vo = new Catalog2Vo.Catalog3Vo(level2.getCatId().toString(), level3.getCatId().toString(), level3.getName());
                            return catalog3Vo;
                        }).collect(Collectors.toList());
                        //封装catalog3Vo到catalog2Vo
                        catalog2Vo.setCatalog3List(catalog3List);
                    }
                    return catalog2Vo;
                }).collect(Collectors.toList());
            }
            //返回v=catalog2Vo
            return catelog2Vos;
        }));

        return map;

    }

演示的结果图:

 修改数据,缓存消失:

 在刷新首页,缓存修改后的数据

 

 总结如下:

/**
 * Spirng-Cache的不足
 * 1)读模式:
 *    缓存穿透:查询一个null数据。解决:缓存空数据:cache-null-values=true
 *    缓存击穿:大量并发进来同时查询一个正好过期的数据。解决:加锁,默认无锁,sync=true
 *    缓存雪崩:大量的key同时过期。解决:加随机时间。加上过期时间 spring.cache.redis.time-to-live=3600000
 *  2)写模式:(缓存与数据库一致)
 *    1:写入加锁
 *    2:引入canal,感受到mysql的变化
 *    3:读多写多,直接去数据库查询就行
 *  总结:
 *    常规数据(读多写少,即时性,一致性要求不高的数据,完全可以使用spring-cache)
 *    特殊数据:特殊设计
 */

//@MapperScan("com.dalianpai.gulimall.product.dao")
@ComponentScan("com.dalianpai")
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients("com.dalianpai.gulimall.product.feign")
public class GulimallProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimallProductApplication.class, args);
    }

}

猜你喜欢

转载自www.cnblogs.com/dalianpai/p/13205307.html