黑马苍穹外卖学习Day7

文章目录

  • 缓存菜品
    • 实现思路
    • 代码开发
  • 缓存套餐
    • Spring Cache
    • 入门案例
    • 实现思路
    • 代码开发
  • 添加购物车
    • 需求分析和设计
    • 代码开发
  • 查看购物车
    • 需求分析
    • 代码开发
  • 清空购物车
    • 需求分析
    • 代码实现

缓存菜品

实现思路

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码开发

Controller层

@RestController("userDishController")
@Api(tags = "C端-菜品浏览接口")
@RequestMapping("/user/dish")
@Slf4j
public class DishController {@Autowiredprivate DishService dishService;@Autowiredprivate RedisTemplate redisTemplate;/*** 根据分类id查询菜品* @param categoryId* @return*/@GetMapping("/list")@ApiOperation("根据分类id查询菜品")private Result<List<DishVO>> list(Long categoryId){//构造redis中的key,规则:dish_分类idString 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);//查询起售中的菜品//如果不存在,查询数据库,将查询数据库插入到redis中List<DishVO> dishVOS = dishService.listWithFlavor(dish);redisTemplate.opsForValue().set(key, dishVOS);return Result.success(dishVOS);}
}

在新增菜品,修改菜品,批量删除菜品,起售、停售菜品时候都需要清除缓存以便显示最新数据。
可以在每个Controller方法完成后加上

        Set keys = redisTemplate.keys("dish_*");redisTemplate.delete(keys);

可以设计一个清理缓存的方法来替代

    /*** 清理缓存数据* @param pattern*/private void cleanCache(String pattern){Set keys = redisTemplate.keys(pattern);redisTemplate.delete(keys);}

缓存套餐

Spring Cache

在这里插入图片描述
在这里插入图片描述

入门案例

根据demo文件创建数据库和对应的表
在这里插入图片描述

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`id` bigint NOT NULL AUTO_INCREMENT,`name` varchar(45) DEFAULT NULL,`age` int DEFAULT NULL,PRIMARY KEY (`id`)
);

在这里插入图片描述
Controller层

    @Autowiredprivate UserMapper userMapper;//user.id 动态取到用户id,redis通过冒号储存成树形结构@PostMapping@CachePut(cacheNames = "userCache",key = "#user.id")  //将方法的返回值放入缓存,key的生成为:userCache::user.id//@CachePut(cacheNames = "userCache",key = "#result.id") //对象导航//@CachePut(cacheNames = "userCache",key = "#p0.id")//取到第一个参数//@CachePut(cacheNames = "userCache",key = "#a0.id")public User save(@RequestBody User user){userMapper.insert(user);return user;}

实现类加注解

@Slf4j
@SpringBootApplication
@EnableCaching//开去缓存注解功能
public class CacheDemoApplication {public static void main(String[] args) {SpringApplication.run(CacheDemoApplication.class,args);log.info("项目启动成功...");}
}

通过Swagger接口测试。
在这里插入图片描述
其他的常用注解

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {@Autowiredprivate UserMapper userMapper;//user.id 动态取到用户id,redis通过冒号储存成树形结构@PostMapping@CachePut(cacheNames = "userCache",key = "#user.id")  //将方法的返回值放入缓存,key的生成为:userCache::user.id//@CachePut(cacheNames = "userCache",key = "#result.id") //对象导航//@CachePut(cacheNames = "userCache",key = "#p0.id")//取到第一个参数//@CachePut(cacheNames = "userCache",key = "#a0.id")public User save(@RequestBody User user){userMapper.insert(user);return user;}@CacheEvict(cacheNames = "userCache", key = "#id")@DeleteMappingpublic void deleteById(Long id){userMapper.deleteById(id);}@CacheEvict(cacheNames = "userCache" ,allEntries = true)//删除所有键值对缓存@DeleteMapping("/delAll")public void deleteAll(){userMapper.deleteAll();}@Cacheable(cacheNames = "userCache",key = "#id")//key的生成为:userCache::id@GetMappingpublic User getById(Long id){User user = userMapper.getById(id);return user;}

实现思路

在这里插入图片描述

代码开发

    @GetMapping("/list")@ApiOperation("根据分类id查询套餐")@Cacheable(cacheNames = "setmealCache",key = "#categoryId") //key:setmaelCache::categoryIdpublic Result<List<Setmeal>> list(Long categoryId){List<Setmeal> setmeals = setmealService.list(categoryId);return Result.success(setmeals);}
    /*** 新增套餐接口* @param setmealDTO* @return*/@PostMapping@ApiOperation("新增套餐")@CacheEvict(cacheNames = "setmealCache" ,key = "#setmealDTO.categoryId")//key:setmealCache::100public Result save(@RequestBody SetmealDTO setmealDTO){setmealService.save(setmealDTO);return Result.success();}/*** 批量删除套餐* @param ids* @return*/@DeleteMapping@ApiOperation("批量删除套餐")@CacheEvict(cacheNames = "setmealCache",allEntries = true)public Result delete(@RequestParam List<Long> ids){setmealService.deleteBatch(ids);return Result.success();}/*** 修改套餐* @param setmealDTO* @return*/@PutMapping@ApiOperation("修改套餐")@CacheEvict(cacheNames = "setmealCache",allEntries = true)public Result update(@RequestBody SetmealDTO setmealDTO){setmealService.update(setmealDTO);return Result.success();}

添加购物车

需求分析和设计

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
冗余字段在特定条件下可以提高查询速度,比如这里的name,image,amount等。因为这样不用联表查询只用查这一张表就好了。

代码开发

新建Controller层

@RestController
@RequestMapping("/user/shoppingCart")
@Slf4j
@Api(tags = "C端-购物车相关接口")
public class ShoppingCartController {@Autowiredprivate ShoppingCartService shoppingCartService;/*** 添加购物车* @param shoppingCartDTO* @return*/@PostMapping("/add")@ApiOperation("添加购物车")public Result add(@RequestBody ShoppingCartDTO shoppingCartDTO){shoppingCartService.addShoppingCart(shoppingCartDTO);return Result.success();}
}

ServiceImpl

@Slf4j
@Service
public class ShopppingCartServiceImpl implements ShoppingCartService {@Autowiredprivate ShopppingCartMapper shopppingCartMapper;@Autowiredprivate DishMapper dishMapper;@Autowiredprivate SetmealMapper setmealMapper;/*** 添加购物车* @param shoppingCartDTO*/@Overridepublic void addShoppingCart(ShoppingCartDTO shoppingCartDTO) {//判断当前加入购物车的商品已经存在了ShoppingCart shoppingCart =new ShoppingCart();BeanUtils.copyProperties(shoppingCartDTO, shoppingCart);Long userId = BaseContext.getCurrentId();shoppingCart.setUserId(userId);List<ShoppingCart> list = shopppingCartMapper.list(shoppingCart);//如果已经存在了,只需要将数量加一if (list != null && list.size() > 0){ShoppingCart shoppingCart1 = list.get(0);shoppingCart1.setNumber(shoppingCart1.getNumber()+ 1 );//update shopping_cart set number = ? where id = ?shopppingCartMapper.updateNumberById(shoppingCart1);}else{//如果不存在,需要插入一条购物车数据//判断本次添加到购物车的是菜品还是套餐Long dishId = shoppingCartDTO.getDishId();Long setmealId = shoppingCartDTO.getSetmealId();if (dishId != null){//添加到购物车的是菜品Dish dish = dishMapper.getById(dishId);shoppingCart.setName(dish.getName());shoppingCart.setImage(dish.getImage());shoppingCart.setAmount(dish.getPrice());}else {//本次添加的就是套餐Setmeal setmeal = setmealMapper.getById(setmealId);shoppingCart.setName(setmeal.getName());shoppingCart.setImage(setmeal.getImage());shoppingCart.setAmount(setmeal.getPrice());}shoppingCart.setNumber(1);shoppingCart.setCreateTime(LocalDateTime.now());//统一插入shopppingCartMapper.insert(shoppingCart);}}
}

Mapper接口

@Mapper
public interface ShopppingCartMapper {/*** 动态条件查询* @param shoppingCart* @return*/List<ShoppingCart> list(ShoppingCart shoppingCart);/*** 根据id修改商品数量* @param shoppingCart*/@Update("update shopping_cart set number = #{number} where id = #{id}")void updateNumberById(ShoppingCart shoppingCart);/*** 插入购物车数据* @param shoppingCart*/@Insert("insert into shopping_cart (name, image, user_id, dish_id, setmeal_id, dish_flavor, amount, number, create_time) VALUES " +"(#{name} ,#{image} ,#{userId} ,#{dishId} ,#{setmealId} ,#{dishFlavor} ,#{amount} ,#{number} ,#{createTime} )")void insert(ShoppingCart shoppingCart);
}

XML

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sky.mapper.ShopppingCartMapper"><select id="list" resultType="com.sky.entity.ShoppingCart">select * from shopping_cart<where><if test="userId != null">and user_id = #{userId}</if><if test="setmealId != null">and setmeal_id = #{setmealId}</if><if test="dishId != null">and dish_id = #{dishId}</if><if test="dishFlavor != null">and dish_flavor = #{dishFlavor}</if></where></select>
</mapper>

查看购物车

需求分析

在这里插入图片描述
在这里插入图片描述

代码开发

Controller层

    /*** 查看购物车* @return*/@GetMapping("/list")@ApiOperation("查看购物车")public Result<List<ShoppingCart>> list(){List<ShoppingCart> shoppingCarts = shoppingCartService.showShopppingCart();return Result.success(shoppingCarts);}

Service实现类

    /*** 查看购物车* @return*/@Overridepublic List<ShoppingCart> showShopppingCart() {Long userId = BaseContext.getCurrentId();ShoppingCart shoppingCart = ShoppingCart.builder().userId(userId).build();List<ShoppingCart> list = shopppingCartMapper.list(shoppingCart);return list;}

清空购物车

需求分析

在这里插入图片描述
在这里插入图片描述

代码实现

Controller层

    /*** 清空购物车* @return*/@DeleteMapping("/clean")@ApiOperation("清空购物车")public Result clean(){shoppingCartService.cleanShoppingCart();return Result.success();}

Service实现类

    /*** 清空购物车*/@Overridepublic void cleanShoppingCart() {Long userId = BaseContext.getCurrentId();shopppingCartMapper.deleteByUserId(userId);}

Mapper接口

    /*** 清空购物车* @param userId*/@Delete("delete from shopping_cart where user_id = #{userId}")void deleteByUserId(Long userId);

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

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

相关文章

2024.1.16 GCC 编译选项 屏蔽某些警告 CMAKE_CXX_FLAGS

gcc警告选项汇总 请求或取消警告的选项 警告是诊断消息&#xff0c;报告的结构本质上不是错误的&#xff0c;但是有风险或表明可能有错误。 以下与语言无关的选项不会启用特定的警告&#xff0c;但会控制GCC生成的诊断类型。 -fsyntax-only 检查代码中的语法错误&#xff0c;…

ROS第 6 课 编写简单的订阅器 Subscriber

文章目录 第 6 课 编写简单的订阅器 Subscriber1. 编写订阅者节点2. 测试发布者和订阅者 第 6 课 编写简单的订阅器 Subscriber 订阅器是基于编辑了发布器的基础上创建的&#xff0c;只有发布了消息&#xff0c;才有可能订阅。若未编辑发布器&#xff0c;可前往"ROS第5课 …

FlinkSQL【分组聚合-多维分析-性能调优】应用实例分析

FlinkSQL处理如下实时数据需求&#xff1a; 实时聚合不同 类型/账号/发布时间 的各个指标数据&#xff0c;比如&#xff1a;初始化/初始化后删除/初始化后取消/推送/成功/失败 的指标数据。要求实时产出指标数据&#xff0c;数据源是mysql cdc binlog数据。 代码实例 --SET t…

解决kali beef启动失败解问题

只限于出现这个提示的时候使用 卸载 ruby apt remove ruby 卸载 beef apt remove beef-xss 重新安装ruby apt-get install ruby apt-get install ruby-dev libpcap-dev gem install eventmachine 重新安装beef apt-get install beef-xss 弄完以上步骤如果还是不行就重启kali再试…

cmake构建动态库实例(cmakelist)

文章目录 一、开发实例1.1 代码目录1.2 代码内容1.2.1 CMakeLists.txt1.2.2 mylib.cpp1.2.2 mylib.h1.2 编译二、动态库使用方法一、动态链接源代码构建运行方法二:dlopen方式一、开发实例 通过cmake构建静态开发实例如下: 1.1 代码目录 代码目录结构如下:

nestjs 装饰器

1、装饰器定义 装饰器是一种特殊的类型声明&#xff0c;它可以附加在类、方法、属性、参数上边 需开启tsconfig.json中 "experimentalDecorators":true 生成tsconfig.json文件 tsc -init 2、类装饰器 // 类装饰器 主要是通过符号添加装饰器 // 装饰器会自动把cl…

CCC数字钥匙标准3.0版本解读(23)

文章目录 17.8 数据结构定义17.8.1 请求报头17.8.2 响应报头17.8.3 Key类型17.8.4 EncryptedDataContainer17.8.5 未加密的uiBundle17.8.6 数字钥匙状态17.8.7 manageKey操作类型17.8.8 钥匙操作类型17.8.9 通知的事件类型17.8.10 事件通知的事件数据17.8.11 未加密的时间通知数…

【MySQL】MySQL表的增删查改以及聚合函数/group by句子的使用

文章目录 一、创建--Create1.单行数据 全列插入2.多行数据 指定列插入3.插入否则更新4.替换 -- replace 二、读取--Retrieve1.SELECT列1.1全列查询1.2指定列查询1.3查询字段为表达式1.4为查询结果指定别名1.5 结果去重 -- distinct 2.WHERE 条件3.结果排序4.筛选分页结果 三、…

《数据结构》学习笔记

1.算法分析的两个主要任务&#xff1a;正确性&#xff08;不变性 单调性&#xff09; 复杂度。 2.复杂度分析的主要方法&#xff1a; 迭代&#xff1a;级数求和&#xff1b;递归&#xff1a;递归跟踪 递推方程猜测 验证 3.级数&#xff1a; &#xff08;1&#xff09;算…

LLM之RAG实战(十六)| 使用Llama-2、PgVector和LlamaIndex构建LLM Rag Pipeline

近年来&#xff0c;大型语言模型&#xff08;LLM&#xff09;取得了显著的进步&#xff0c;然而大模型缺点之一是幻觉问题&#xff0c;即“一本正经的胡说八道”。其中RAG&#xff08;Retrieval Augmented Generation&#xff0c;检索增强生成&#xff09;是解决幻觉比较有效的…

智能小程序小部件(Widget)表单组件属性说明+代码明细

在 Tuya MiniApp Tools 中&#xff0c;新建项目并选择小部件(Widget)对应模板即可自动创建小部件(Widget)项目。 button 按钮&#xff0c;用于强调操作并引导用户去点击。 属性说明 属性名类型默认值必填说明sizestringdefault否按钮的大小typestringdefault否按钮的样式类…

opencv_角点检测

文章内容 一个opencv检测角点的程序 运行效果 #include <opencv2/opencv.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream>using namespace cv; using namespace std;void detectCorners(M…

低代码-详情页组件设计

详情页数据结构定义 layout:{// 按钮数据buttonLayout:{headButton:[], // 页头按钮footButton:[] // 页脚按钮},// 详情页表单配置config:{}, // 配置组件列表detailLayout:[]}默认行为 进表单初始化&#xff0c;只展示表单属性&#xff0c;隐藏通用、数据、事件tab项。 配…

低代码自动化平台| 游戏规则改变者

自动化测试对于软件开发公司起着非常重要的作用。它在公司及其客户之间建立了对优质产品的信任。此外&#xff0c;它还使软件开发人员更加自信&#xff0c;因为他们可以在其他模块上工作&#xff0c;而不必担心应用程序的任何现有功能是否存在错误。在软件测试中融入自动化是必…

数据分析-Pandas如何整合多张数据表

数据分析-Pandas如何整合多张数据表 数据表&#xff0c;时间序列数据在数据分析建模中很常见&#xff0c;例如天气预报&#xff0c;空气状态监测&#xff0c;股票交易等金融场景。数据分析过程中重新调整&#xff0c;重塑数据表是很重要的技巧&#xff0c;此处选择Titanic数据…

多测师肖sir___ui自动化测试po框架(升级)

ui自动化测试po框架&#xff08;升级&#xff09; po框架 一、ui自动化po框架介绍 &#xff08;1&#xff09;PO是Page Object的缩写&#xff08;pom模型&#xff09; &#xff08;2&#xff09;业务流程与页面元素操作分离的模式&#xff0c;可以简单理解为每个页面下面都有一…

【linux】visudo

碎碎念 visudo命令是用来修改一个叫做 /etc/sudoers 的文件的&#xff0c;用来设置哪些 用户 和 组 可以使用sudo命令。并且使用visudo而不是使用 vi /etc/sudoers 的原因在于&#xff1a;visudo自带了检查功能&#xff0c;可以判断是否存在语法问题&#xff0c;所以更加安全 …

深入探讨 Go 语言中的 Map 类型(续)

深入探讨 Go 语言中的 Map 类型&#xff08;续&#xff09; 在上一篇博客中&#xff0c;我们已经讨论了 Go 语言中 map 类型的基本概念、特性以及最佳实践。本篇继续深入&#xff0c;讨论一些更高级的 map 用法和技巧&#xff0c;以及一些注意事项。 更高级的 Map 用法 1. m…

7.评价预测模型——C指数,NRI,IDI计算

目录 基本知识 1. C指数 2. NRI、IDI 二分类资料 1. C指数 C指数计算 比较两个模型C指数 2. NRI 3. IDI 生存资料 1. rms包拟合的生存曲线 C指数 比较两个模型的C指数 2. survival包拟合的生存曲线 C指数 NRI计算 IDI 基本知识 1. C指数 C指数&#xff1a; …

给VScode 挪挪窝

给VSCode 挪挪窝 vscode platoformio 写一些代码&#xff0c;导致笔记本c盘满满当当的&#xff0c; 挪了几次都不成功&#xff0c;今天学了一招&#xff0c;给这俩挪到另外一个盘去 复制文件 cp -R c:\users\user\.vscode d:\work\tools\PIO\.vscode cp -R c:\users\user…