首页 > 其他分享 >缓存菜品数据

缓存菜品数据

时间:2023-04-06 14:35:54浏览次数:38  
标签:缓存 dishDto key 菜品 dish 数据 redisTemplate

实现思路:

  前面已经实现了移动端菜品查看功能,对应的服务端方法为DishController中的list方法,此方法会根据前端提交的查询条件进行数据库查询操作。在高并发的情况下,频繁查询数据库会导致系统性能下降,服务端响应时间增长。现在需要对此方法进行缓存优化,提高系统的性能

具体的实现思路:

  1、改造DishController的list方法,先从Redis中获取菜品数据,如果有则直接返回,无需查询数据库;如果没有则查询数据库,并将查询到的菜品数据放入Redis中

  2、改造DishController的save和update方法,加入清理缓存的逻辑

注意:在使用缓存时,要注意数据库中的数据和缓存中的数据一致,如果数据库中的数据发生变化,需要及时清理缓存数据

  

 @GetMapping("/list")
    public R<List<DishDto>> list(Dish dish){

        List<DishDto> dishDtos = null;

        //动态构造key
        String key = "dish_" + dish.getCategoryId() + "_" + dish.getStatus();
        //先从redis中获取缓存数据
        dishDtos = (List<DishDto>)redisTemplate.opsForValue().get(key);
        if(dishDtos!=null){
            //如果存在,直接返回,无需查询数据库
            return R.success(dishDtos);
        }

        //如果不存在,需要查询数据库,将查询到的菜品数据缓存到Redis
        Long categoryId = dish.getCategoryId();
        //构造条件查询
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(categoryId!=null, Dish::getCategoryId, categoryId);
        //添加排序条件
        queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
        //查询status=1启售的菜品
        queryWrapper.eq(Dish::getStatus, 1);
        List<Dish> dishes = dishService.list(queryWrapper);
        //将菜品和对应口味信息封装到dishDto
        dishDtos = dishes.stream().map((item) -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item, dishDto);
            //根据菜品id查询对应的口味
            LambdaQueryWrapper<DishFlavor> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(DishFlavor::getDishId, item.getId());
            List<DishFlavor> flavors = dishFlavorService.list(lambdaQueryWrapper);
            dishDto.setFlavors(flavors);
            return dishDto;
        }).collect(Collectors.toList());
        //如果不存在,需要查询数据库,将查询到的菜品数据缓存到Redis
        redisTemplate.opsForValue().set(key, dishDtos, 60, TimeUnit.MINUTES);
        return R.success(dishDtos);
    }

 

 /**
     * 将菜品和菜品风味保存到对应的表里面(新增)
     * @return
     */
    @PostMapping
    public R<String> save(@RequestBody DishDto dishDto){
        dishService.saveWithFlavor(dishDto);
        //log.info(dishDto.toString());

        //清理所有菜品的缓存数据
        // Set keys = redisTemplate.keys("dish_*");
        //redisTemplate.delete(keys);

        //清理某个分类下面的菜品缓存数据
        String key = "dish_" + dishDto.getCategoryId() + "_1";
        redisTemplate.delete(key);
        return R.success("新增菜品成功");
    }
 /**
     * 修改菜品
     * @param dishDto
     * @return
     */
    @PutMapping
    public R<String> update(@RequestBody DishDto dishDto){
        dishService.updateWithFlavor(dishDto);

        //清理所有菜品的缓存数据
        // Set keys = redisTemplate.keys("dish_*");
        //redisTemplate.delete(keys);

        //清理某个分类下面的菜品缓存数据
        String key = "dish_" + dishDto.getCategoryId() + "_1";
        redisTemplate.delete(key);


        return R.success("修改成功");
    }

 

标签:缓存,dishDto,key,菜品,dish,数据,redisTemplate
From: https://www.cnblogs.com/fxzm/p/17287984.html

相关文章

  • 面试突击MySQL:高并发情况下,数据库该如何设计?
    转载:http://blog.itpub.net/70000181/viewspace-2776766/面试题剖析为什么要分库分表?(设计高并发系统的时候,数据库层面该如何设计?)说白了,分库分表是两回事儿,大家可别搞混了,可能是光分库不分表,也可能是光分表不分库,都有可能。我先给大家抛出来一个场景:假如我们现在是一个小创业公......
  • 2023.04.06 - 使用mixin动态混入,对vue组件中的数据做兼容经验总结(xp)
    业务场景:在一个高拍仪的硬件设备中,厂家给了两套不同的API,分别支持winXP和winXP以上版本的系统,而这两套API的实现方式截然不同,一套使用的是http通信,一套是使用scoket通信,方法的调用自然也是不同。我需要在同一组件兼容这两套代码。这种需求下很明显,我除了修改组件里的函数方法,......
  • 子线程中获取父线程的数据(线程池下失效)
    子线程中获取父线程的数据staticInheritableThreadLocal<String>local=newInheritableThreadLocal<>();publicstaticvoidmain(String[]args){local.set("123");System.out.println(Thread.currentThread().getName()+&qu......
  • 架构师日记-为什么数据一致性那么难
    作者:京东零售 刘慧卿一前言在现代大型分布式软件系统中,有一个绕不过去的课题,那就是如何保证系统的数据一致性。著名的Paxos算法(Megastore、Spanner),Raft协议(ETCD、TiKV、Consul),ZAB协议(ZooKeeper)等分布式一致性解决方案,都是在此背景下而诞生的。数据一致性保障为什么难呢?先来看一......
  • 1688关键字搜索新品数据API接口(item_search_new-按关键字搜索新品数据)
    1688关键字搜索新品数据API接口(item_search_new-按关键字搜索新品数据)代码接口教程如下:公共参数名称类型必须描述key String 是 调用key(必须以GET方式拼接在URL中)secret String 是 调用密钥api_name String 是 API接口名称(包括在请求地址中)[item_search,item_get,item_search......
  • SqlServer数据库表生成C# Model实体类SQL语句
    DECLARE@TableNamesysname='tb_Customer';DECLARE@ResultVARCHAR(MAX)='publicclass'+@TableName+'{';SELECT@Result=@Result+'///<summary>///'+CAST(t.SummaryASVARCHAR(MAX))+&#......
  • 自动化测试当中的三大设计技巧:PO设计思想,数据驱动及关键字驱动
    大家好,我是洋子。当我们以离线脚本的形式编写了大量的自动化测试代码后,很容易发现以下常见问题:(1)对于UI自动化,当UI层的元素发生改变,需要修改所有相关的case,工作量巨大(2)代码难以扩展,每次想新增一个自动化case就要写新的逻辑,补充新的代码(3)代码可读性差,代码冗余,存在大量重复代码或者......
  • 走进Java接口测试之从0到1搭建数据驱动框架(需求篇)
    前言一个“好的”数据驱动框架,需要从“时间”、“人力”、“收益”这三个方面出发,做好“取舍”。不能由于被测业务系统发生一些变更,就导致花费了几个小时的脚本无法执行。同时,我们需要看到“收益”,不能为了总想看到100%的成功,而减少必须做的工作,这导致可能都需要进行大量的维护。......
  • 数据库open遭遇ora-01555错误
    前几天我们的一位准客户的其中一套较为重要的数据库出现了故障。我们这里先姑且不去分析原因,来将数据库打开提供业务恢复再说。首先我们来看下一线工程师现场发回的报道:ORA-01555causedbySQLstatementbelow(SQLID:4krwuz0ctqxdt,SCN:0x0e0a.938dbd1d):selectctime,mti......
  • 读取配置文件的配置字典数据(字典数据包含中文)
        项目有时为了方便配置数据字典,会创建类似于“test=测试”的key-value形式的数据字典,在项目启动时便缓存该字典数据,方便后续使用;但是该字典有时候又存在中文,在加载之后会出现乱码问题,便需要对加载的数据进行特殊处理。publicclassConfigUtils{/***加......