黑马苍穹外卖6 清理redis缓存+Spring Cache+购物车的增删改查

缓存菜品

后端服务都去查询数据库,对数据库访问压力增大。
解决方式:使用redis来缓存菜品,用内存比磁盘性能更高。
在这里插入图片描述
在这里插入图片描述
key :dish_分类id
String key= “dish_” + categoryId;

@RestController("userDishController")
@RequestMapping("/user/dish")
@Slf4j
@Api(tags = "C端-菜品浏览接口")
public class DishController {@Autowiredprivate DishService dishService;@Autowiredprivate RedisTemplate redisTemplate;//注入redis对象/*** 根据分类id查询菜品** @param categoryId* @return*/@GetMapping("/list")@ApiOperation("根据分类id查询菜品")public Result<List<DishVO>> list(Long categoryId) {//构造redis中的key来查询分类下的菜单String key = "dish_" + categoryId;//查询redis中是否存在菜品,有则读取List<DishVO> list = (List<DishVO>) redisTemplate.opsForValue().get(key);if (list!=null&&list.size()>0 ){return Result.success(list);}//如果不存在,查询数据库并构造缓存Dish dish = new Dish();dish.setCategoryId(categoryId);dish.setStatus(StatusConstant.ENABLE);//查询起售中的菜品list = dishService.listWithFlavor(dish);redisTemplate.opsForValue().set(key,list);return Result.success(list);}}

当数据变更[增删改]时要清除缓存

private void cleanCache(String pattern) {Set keys = redisTemplate.keys(pattern);redisTemplate.delete(keys);}
@ApiOperation("批量删除菜品")@DeleteMappingpublic Result delete(@RequestParam List<Long> ids) {//@RequestParam让Spring去解析字符串,然后将分割的字符封装到集合对象中dishService.deleteBatch(ids);//批量删除//更新缓存,清理所有,将所有的菜品缓存数据清理,所有以dish_开头的keycleanCache("dish_*");return Result.success();}
@PostMapping@ApiOperation("菜品新增")public Result save(@RequestBody DishDTO dishDTO) {dishService.saveWithFlavor(dishDTO);//清理缓存cleanCache("dish_" + dishDTO.getCategoryId());//精确清理return Result.success();}

缓存套餐

Spring Cache

框架,实现了基于注解的缓存功能。
底层可以切换不同的缓存实现:
EHCache
Caffeine
Redis
在这里插入图片描述
@CachePut这个注释将方法的返回结果,user对象保存到Redis中,同时生成动态的key,userCache::user.id

@CachePut(cacheNames="userCache",key="abs")//Spring Cache缓存数据,key的生成:userCache:abc
@CachePut(cacheNames="userCache",key="#user.id")//与形参保持一致,或者
@CachePut(cacheNames="userCache",key="#result.id")//返回值result,或者
@CachePut(cacheNames="userCache",key="#p0.id")//获得当前方法的第一个参数user,或者
@CachePut(cacheNames="userCache",key="#a0.id")//获得当前方法的第一个参数user,或者
@CachePut(cacheNames="userCache",key="#root.args[0].id")//获得当前方法的第一个参数user
public User save(@RequestBody User user){userMapper.insert(user);return result;
}

插入完数据后,数据库生成的主键值会自动赋给user对象
Redis可以形成树形结构

@Cacheable注解

@Cacheable(cahceNames="userCache"),key="#id")//key的生成,userCache::10
public User getById(Long id){User user = userMapper.getById(id);return user;
}

@CacheEvict一次清理一条数据

@CacheEvict(cahceNames="userCache"),key="#id")//key的生成,userCache::10
public void deleteById(Long id){userMapper.deleteById(id);
}

清除所有数据

@CacheEvict(cahceNames="userCache"),allEntries=true)//userCache下的所有键值对
public void deleteAlld(){userMapper.deleteAll();
}

回归项目:缓存套餐
1.展示套餐—先查cache中,再数据库查+导Redis

 @GetMapping("/list")@ApiOperation("根据分类id查询套餐")@Cacheable(cacheNames = "setMealCache",key = "#categoryId")//key : setMealCache::1public Result<List<Setmeal>> list(Long categoryId) {Setmeal setmeal = new Setmeal();setmeal.setCategoryId(categoryId);setmeal.setStatus(StatusConstant.ENABLE);List<Setmeal> list = setmealService.list(setmeal);return Result.success(list);}

2.增删

 @PostMapping@ApiOperation("新增套餐")@CacheEvict(cacheNames = "setMealCache",key = "#setmealDTO.categoryId")//精确清理key:setmealCache::100public Result save(@RequestBody SetmealDTO setmealDTO) {setmealService.saveWithDish(setmealDTO);return Result.success();}
@DeleteMapping@ApiOperation("批量删除套餐")@CacheEvict(cacheNames = "setMealCache",allEntries = true)public Result delete(@RequestParam List<Long> ids){setmealService.deleteBatch(ids);return Result.success();}

添加购物车-增改查

在这里插入图片描述

在这里插入图片描述
上图是表中每个字段的属性。
购物车表效果:
在这里插入图片描述

1.增–添加购物车

判断商品是否已经存在,存在就+1,不存在则插入数据
(1)先根据user_id和菜品ID/套餐ID查表
Controller:

@PostMapping("/add")@ApiOperation("添加购物车")public Result add(@RequestBody ShoppingCartDTO shoppingCartDTO){shoppingCartService.add(shoppingCartDTO);return Result.success();}

Setvice:

public void add(ShoppingCartDTO shoppingCartDTO) {ShoppingCart shoppingCart = new ShoppingCart();BeanUtils.copyProperties(shoppingCartDTO, shoppingCart);//属性拷贝Long currentId = BaseContext.getCurrentId();shoppingCart.setUserId(currentId);//先查询购物车中是否存在List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);//查表if (list != null && list.size() > 0) {//存在则更新数据的数量ShoppingCart cart = list.get(0);cart.setNumber(cart.getNumber() + 1);shoppingCartMapper.updateNumberById(cart);//更新表}else {//不存在则添加数据Long dishId = shoppingCart.getDishId();Long setmealId = shoppingCart.getSetmealId();//判断添加的这条是菜还是套餐if (dishId != null) {Dish dish = dishMapper.getById(dishId);shoppingCart.setName(dish.getName());shoppingCart.setAmount(dish.getPrice());shoppingCart.setImage(dish.getImage());} else if (setmealId != null) {Setmeal setmeal = setmealMapper.getById(setmealId);shoppingCart.setImage(setmeal.getImage());shoppingCart.setAmount(setmeal.getPrice());shoppingCart.setName(setmeal.getName());}shoppingCart.setNumber(1);shoppingCart.setCreateTime(LocalDateTime.now());shoppingCartMapper.insert(shoppingCart);//插入表项}}

查:
mapper:

List<ShoppingCart> list(ShoppingCart shoppingCart);

动态xml

<select id="list" resultType="com.sky.entity.ShoppingCart">select * from shopping_cart<where><if test="userId!=null">and user_id=#{userId}</if><if test="dishId!=null">and dish_id=#{dishId}</if><if test="setmealId!=null">and setmeal_id=#{setmealId}</if><if test="dishFlavor!=null">and dish_flavor=#{dishFlavor}</if></where></select>

改:
mapper:

@Update("update shopping_cart set number=#{number} where id=#{id}")void updateNumberById(ShoppingCart shoppingCart);

插:
mapper:

@Insert("insert into shopping_cart(name, image, user_id, dish_id, setmeal_id, dish_flavor, number, amount, create_time)"+ "values (#{name},#{image},#{userId},#{dishId},#{setmealId},#{dishFlavor},#{number},#{amount},#{createTime})")void insert(ShoppingCart shoppingCart);

查看购物车

在这里插入图片描述
Controller:

  @GetMapping("/list")@ApiOperation("查询购物车数据")public Result<List<ShoppingCart>> list(){return Result.success(shoppingCartService.list());}

Service:

@Overridepublic List<ShoppingCart> list() {Long currentId = BaseContext.getCurrentId();ShoppingCart shoppingCart = ShoppingCart//构造对象.builder().userId(currentId).build();return shoppingCartMapper.list(shoppingCart);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/32699.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

批量重命名神器揭秘:一键实现文件夹随机命名,自定义长度轻松搞定!

在数字化时代&#xff0c;我们经常需要管理大量的文件夹&#xff0c;尤其是对于那些需要频繁更改或整理的文件来说&#xff0c;给它们进行批量重命名可以大大提高工作效率。然而&#xff0c;传统的重命名方法既繁琐又耗时&#xff0c;无法满足高效工作的需求。今天&#xff0c;…

ic基础|功耗篇03:ic设计人员如何在代码中降低功耗?一文带你了解行为级以及RTL级低功耗技术

大家好&#xff0c;我是数字小熊饼干&#xff0c;一个练习时长两年半的ic打工人。我在两年前通过自学跨行社招加入了IC行业。现在我打算将这两年的工作经验和当初面试时最常问的一些问题进行总结&#xff0c;并通过汇总成文章的形式进行输出&#xff0c;相信无论你是在职的还是…

TI毫米波雷达可以用串口调试助理来获取原始数据吗?

摘要&#xff1a;本文介绍一下如何使用普通的串口调试助理来读取到AWR1843毫米波雷达的数据的。 使用的硬件如下图所示。 软件就是普通的串口助理&#xff0c;我用的是SSCOM&#xff0c;其他串口助理也是可以的&#xff0c;核心作用其实就是发送一行行的指令而已。 操作方法&am…

20240623(26.0) 重要财经新闻

财经关注 ► 券商中国&#xff1a;北交所于6月21日晚间受理了3家企业的IPO申请。6月20日晚间&#xff0c;沪深交易所各受理了1家IPO申请。这也意味着&#xff0c;三大交易所IPO受理全部恢复。与此同时&#xff0c;三大交易所IPO上市委会议也已经全部重启。 ► 全球多地近期遭遇…

微信小程序学习(六):常用原生 API

&#x1f517;API官方文档 1、网络请求 wx.request({// 接口地址&#xff0c;仅为示例&#xff0c;并非真实的接口地址url: example.php,// 请求的参数data: { x: },// 请求方式 GET|POST|PUT|DELETEmethod: GET,success (res) {console.log(res.data)},fail(err) {console.…

msvcp140.dll丢失的解决方法,msvcp140.dll丢失下载办法

一、msvcp140.dll丢失或损坏的影响 系统更新影响 系统更新是导致msvcp140.dll丢失或损坏的常见原因之一。在自动更新过程中&#xff0c;可能会引入与现有应用程序不兼容的DLL版本&#xff0c;从而引发错误。根据用户反馈和技术支持数据&#xff0c;大约15%的msvcp140.dll问题…

2-3KW户储、家储逆变器设计资料

储能电源方案双向逆变器板资料&#xff0c;原理文件&#xff0c;PCB文件&#xff0c;源代码&#xff0c;bom清单。 bom表&#xff1a; PCB&#xff1a; 变压器电感 2-3KW户储、家储逆变器设计通常需要考虑以下几个方面&#xff1a; 输入电压范围&#xff1a;逆变器需要能够适应…

接口性能优化方法总结

接口性能优化是后端开发人员经常碰到的一道面试题&#xff0c;因为它是一个跟开发语言无关的公共问题。 这个问题既可以很简单&#xff0c;也可以相当复杂。 导致接口性能问题的原因多种多样&#xff0c;不同项目的不同接口&#xff0c;其原因可能各不相同。 下面列举几种常…

2024-6-18(沉默Spring,Springboot)

1.Spring小结 我们最后再来体会一下用 Spring 创建对象的过程&#xff1a; 通过 ApplicationContext 这个 IoC 容器的入口&#xff0c;用它的两个具体的实现子类&#xff0c;从 class path 或者 file path 中读取数据&#xff0c;用 getBean() 获取具体的 bean instance。 那…

oracle发送https请求

参照 https://docs.oracle.com/cd/E11882_01/appdev.112/e40758/u_http.htm#i1025869 https://docs.oracle.com/cd/E11882_01/network.112/e40393/asowalet.htm#ASOAG160 https://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_networkacl_adm.htm#ARPLS148 https://d…

Tailwindcss 提取组件

背景 随着项目的发展&#xff0c;您不可避免地会发现自己需要重复使用常用样式&#xff0c;以便在许多不同的地方重新创建相同的组件。这在小组件&#xff08;如按钮、表单元素、徽章等&#xff09;中最为明显。在我的项目中是图表标题样式如下&#xff1a; <div class&qu…

基于Openmv的色块识别代码及注意事项

在给出代码之前我先说注意事项以及需要用到的函数 1、白平衡和自动增益的关闭 打开白平衡和自动增益会影响颜色识别的效果&#xff0c;具体影响体现在可能使你颜色阈值发生改变 关闭代码如下 sensor.set_auto_gain(False) #关闭自动增益 sensor.set_whitebal(False) …

喜报!极限科技新获得一项国家发明专利授权:“搜索数据库的正排索引处理方法、装置、介质和设备”

近日&#xff0c;极限数据&#xff08;北京&#xff09;科技有限公司&#xff08;简称&#xff1a;极限科技&#xff09;新获得一项国家发明专利授权&#xff0c;专利名为 “搜索数据库的正排索引处理方法、装置、介质和设备”&#xff0c;专利号&#xff1a;ZL 2024 1 0479400…

Node.js版Selenium WebDriver教程

目录 介绍 导言 Selenium基础 环境设置 使用npm安装selenium-webdriver模块 配置和管理浏览器驱动器 下载火狐 下载安装 webDriver 第一个WebDriver脚本 介绍 导言 在当今数字化时代&#xff0c;Web应用程序的质量和性能至关重要。为了确保这些应用的可靠性&#xf…

我国人工智能核心产业规模近6000亿元

以下文章来源&#xff1a;中国证券报 2024世界智能产业博览会6月20日至6月23日在天津举行。会上发布的《中国新一代人工智能科技产业发展报告2024》显示&#xff0c;我国人工智能企业数量已经超过4000家&#xff0c;人工智能已成为新一轮科技革命和产业变革的重要驱动力量和战略…

【数据结构】链表的大概认识及单链表的实现

目录 一、链表的概念及结构 二、链表的分类 三、单链表的实现 建立链表的节点&#xff1a; 尾插——尾删&#xff1a; 头插——头删&#xff1a; 查找&#xff1a; 指定位置之后删除——插入&#xff1a; 指定位置之前插入——删除指定位置&#xff1a; 销毁链表&am…

【GD32】从零开始学兆易创新32位微处理器——RTC实时时钟+日历例程

1 简介 RTC实时时钟顾名思义作用和墙上挂的时钟差不多&#xff0c;都是用于记录时间和日历&#xff0c;同时也有闹钟的功能。从硬件实现上来说&#xff0c;其实它就是一个特殊的计时器&#xff0c;它内部有一个32位的寄存器用于计时。RTC在低功耗应用中可以说相当重要&#xf…

stm32学习笔记---OLED调试工具(理论部分和代码部分)

目录 理论部分 三种常用的程序调试方法 第一种是串口调试 第二种是显示屏调试 第三种是Keil调试模式 其他调试方式 OLED显示屏的介绍 OLED的硬件电路 OLED驱动程序中所包含的驱动函数 OLED_Init(); OLED_Clear(); OLED的显示函数 OLED_ShowChar(1, 1, A); OLED_S…

【教学类-36-09】20240622钓鱼(通义万相)-A4各种大小的鱼

背景需求&#xff1a; 用通义万相获得大量的简笔画鱼的图片&#xff0c;制作成不同大小&#xff0c;幼儿用吸铁石钓鱼的纸片&#xff08;回形针&#xff09;&#xff0c;涂色、排序等 补一张通义万相的鱼图 素材准备 &#xff08;一&#xff09;优质的鱼图片 &#xff08;二&a…

獭崎酱酒:传承百年酱香,品味经典之选

在中国白酒文化中&#xff0c;酱香型白酒以其独特的风味和精湛的酿造工艺&#xff0c;一直受到广大酒友的青睐。而在众多酱香型白酒品牌中&#xff0c;獭崎酱酒以其传承百年的酱香工艺和高品质的产品&#xff0c;成为了众多酒友心中的经典之选。    | | | |–|–| | | | 百…