缓存菜品、套餐、购物车相关功能

news/2024/4/27 13:58:00/文章来源:https://blog.csdn.net/m0_64703222/article/details/137046207

一、缓存菜品

通过缓存的方式提高查询性能

1.1问题说明

大量的用户访问导致数据库访问压力增大,造成系统响应慢,用户体验差

1.2 实现思路

优先查询缓存,如果缓存没有再去查询数据库,然后载入缓存

将菜品集合序列化后缓存入redis  key为每个分类的id

1.3 代码开发(缓存菜品)

import com.sky.constant.StatusConstant;
import com.sky.entity.Dish;
import com.sky.result.Result;
import com.sky.service.DishService;
import com.sky.vo.DishVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;@RestController("userDishController")
@RequestMapping("/user/dish")
@Slf4j
@Api(tags = "C端-菜品浏览接口")
public class DishController {@Autowiredprivate DishService dishService;@Autowiredprivate RedisTemplate redisTemplate;/*** 根据分类id查询菜品** @param categoryId* @return*/@GetMapping("/list")@ApiOperation("根据分类id查询菜品")public 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);}//如果不存在,查询数据库,将查询到的数据放入redis中Dish dish = new Dish();dish.setCategoryId(categoryId);dish.setStatus(StatusConstant.ENABLE);//查询起售中的菜品list = dishService.listWithFlavor(dish);redisTemplate.opsForValue().set(key,list);return Result.success(list);}}

1.4 代码开发(清除缓存)

为什么要清除缓存? 为了保证数据的一致性,数据库修改后,缓存中的数据并没有发生改变,用户再次请求后不会请求到新修改的数据,而是过期的数据所以要清除缓存。

什么时候清除缓存? 后端修改数据后对缓存进行及时的清除

    /*** 统一清除缓存数据* @param pattern*/private void cleanCache(String pattern){Set keys = redisTemplate.keys(pattern);redisTemplate.delete(keys);}}
 /*** 启用禁用菜品* @param status* @param id* @return*/@PostMapping("/status/{status}")@ApiOperation("启用禁用菜品")public Result startOrStop(@PathVariable Integer status,Long id){log.info("启用禁用菜品,{},{}",status,id);dishService.startOrStop(status,id);//将所有的菜品缓存数据清理掉,所有以dish_开头的key
//        Set keys = redisTemplate.keys("dish_");
//        redisTemplate.delete(keys);cleanCache("dish_*");return Result.success();}

二、缓存套餐(基于SpringCache)

2.1 SpringCache

  • 被写死了(没有意义)
    @CachePut(cacheNames ="userCache",key = "abc")//如果使用SpringCache缓存数据,key的生成:userCache::abc            //生成的key 与cacheNames,key有关系 
  • 动态生成key  + SpEL表达式
    @CachePut(cacheNames ="userCache",key = "#user.id")//如果使用SpringCache缓存数据,key的生成:userCache::#user.id

2.2 入门案例

1.CachePut:将方法返回值放到缓存中

//    @CachePut(cacheNames ="userCache",key = "#user.id")//如果使用SpringCache缓存数据,key的生成:userCache::abc@PostMapping
//    @CachePut(cacheNames = "userCache",key ="#result.id")//对象导航
//    @CachePut(cacheNames = "userCache",key = "#p0.id")//#p0代表第一个参数
//    @CachePut(cacheNames = "userCache",key = "#a0.id")@CachePut(cacheNames = "userCache",key = "#root.args[0].id")//#root.args[0]代表第一个参数public User save(@RequestBody User user){userMapper.insert(user);return user;}

2.Cacheable:在方法执行前先查询缓存,如果缓存中有该数据,直接返回缓存中的数据。如果没有在方法执行后再将返回值放入缓存中

    @GetMapping@Cacheable(cacheNames = "userCache",key = "#id")public User getById(Long id){User user = userMapper.getById(id);return user;}

Cacheable 不能使用#result.id这种方式设置key的值 

3.CacheEvict :将一条或者多条数据从缓存中删除

  • 删除单条数据
    @CacheEvict(cacheNames = "userCache",key ="#id" )@DeleteMappingpublic void deleteById(Long id){userMapper.deleteById(id);}
  • 删除多条数据(allEntries = true)
    @CacheEvict(cacheNames = "userCache",allEntries = true)@DeleteMapping("/delAll")public void deleteAll(){userMapper.deleteAll();}

2.3实现思路

2.4代码开发

import com.sky.constant.StatusConstant;
import com.sky.entity.Setmeal;
import com.sky.result.Result;
import com.sky.service.SetmealService;
import com.sky.vo.DishItemVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;@RestController("userSetmealController")
@RequestMapping("/user/setmeal")
@Api(tags = "C端-套餐浏览接口")
public class SetmealController {@Autowiredprivate SetmealService setmealService;/*** 条件查询** @param categoryId* @return*/@Cacheable(cacheNames = "setmealCache",key = "#categoryId")//key :setmealCache::100@GetMapping("/list")@ApiOperation("根据分类id查询套餐")public 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);}/*** 根据套餐id查询包含的菜品列表** @param id* @return*/@GetMapping("/dish/{id}")@ApiOperation("根据套餐id查询包含的菜品列表")public Result<List<DishItemVO>> dishList(@PathVariable("id") Long id) {List<DishItemVO> list = setmealService.getDishItemById(id);return Result.success(list);}
}
import com.github.pagehelper.Page;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.SetmealService;
import com.sky.vo.SetmealVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.web.bind.annotation.*;import java.util.List;/*** 套餐管理*/
@RestController
@RequestMapping("/admin/setmeal")
@Api(tags = "套餐管理相关接口")
@Slf4j
public class SetmealController {@Autowiredprivate SetmealService setmealService;@CacheEvict(cacheNames = "setmealCache",key = "setmealDTO.categoryId")@PostMapping@ApiOperation("新增套餐接口")public Result save(@RequestBody SetmealDTO setmealDTO){log.info("新增套餐:{}",setmealDTO);setmealService.saveWithDish(setmealDTO);return Result.success();}/*** 套餐分页查询* @param setmealPageQueryDTO* @return*/@GetMapping("/page")@ApiOperation("套餐分页查询")public Result<PageResult> pageQuery(SetmealPageQueryDTO setmealPageQueryDTO){log.info("套餐分页查询:{}",setmealPageQueryDTO);PageResult pageResult  = setmealService.pageQuery(setmealPageQueryDTO);return Result.success(pageResult);}/*** 批量删除套餐* @param ids* @return*/@CacheEvict(cacheNames = "setmealCache",allEntries = true)@DeleteMapping@ApiOperation("批量删除菜品")public Result delete(@RequestParam List<Long> ids){log.info("批量删除套餐:{}",ids);setmealService.deleteBatch(ids);return Result.success();}/*** 根据id查询套餐,用于修改页面回显数据** @param id* @return*/@GetMapping("/{id}")@ApiOperation("根据id查询套餐")public Result<SetmealVO> getById(@PathVariable Long id) {SetmealVO setmealVO = setmealService.getByIdWithDish(id);return Result.success(setmealVO);}/*** 修改套餐** @param setmealDTO* @return*/@CacheEvict(cacheNames = "setmealCache",allEntries = true)@PutMapping@ApiOperation("修改套餐")public Result update(@RequestBody SetmealDTO setmealDTO) {setmealService.update(setmealDTO);return Result.success();}/*** 套餐起售停售* @param status* @param id* @return*/@CacheEvict(cacheNames = "setmealCache",allEntries = true)@PostMapping("/status/{status}")@ApiOperation("套餐起售停售")public Result startOrStop(@PathVariable Integer status, Long id) {setmealService.startOrStop(status, id);return Result.success();}}

三、添加购物车

3.1需求分析和设计

3.2 代码开发

3.2.1Controller

import com.sky.dto.ShoppingCartDTO;
import com.sky.result.Result;
import com.sky.service.ShoppingCartService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/user/shoppingCart")
@Api(tags = "C端购物车相关接口")
@Slf4j
public class ShoppingCartController {@Autowiredprivate ShoppingCartService shoppingCartService;/*** 添加购物车* @param shoppingCartDTO* @return*/@PostMapping("/add")@ApiOperation("添加购物车")public Result add(@RequestBody ShoppingCartDTO shoppingCartDTO){log.info("添加购物车,商品信息为:",shoppingCartDTO);shoppingCartService.addShoppingCart(shoppingCartDTO);return Result.success();}}

 3.2.2 Serveice层

import com.sky.context.BaseContext;
import com.sky.dto.ShoppingCartDTO;
import com.sky.entity.Dish;
import com.sky.entity.Setmeal;
import com.sky.entity.ShoppingCart;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.service.ShoppingCartService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.time.LocalDateTime;
import java.util.List;@Service
@Slf4j
public class ShoppingCartServiceImpl implements ShoppingCartService {@Autowiredprivate ShoppingCartMapper shoppingCartMapper;@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 = shoppingCartMapper.list(shoppingCart);//如果已经存在了,只需要将其数量加1if (list !=null && list.size()>0){ShoppingCart cart = list.get(0);cart.setNumber(cart.getNumber()+1);shoppingCartMapper.updateNumberById(cart);}else {//如果不存在,需要插入一条购物车数据//判断本次添加购物车的是菜品还是套餐Long dishId = shoppingCartDTO.getDishId();if (dishId !=null){//本次添加的是菜品Dish dish = dishMapper.getById(dishId);shoppingCart.setName(dish.getName());shoppingCart.setImage(dish.getImage());shoppingCart.setAmount(dish.getPrice());
//                shoppingCart.setNumber(1);
//                shoppingCart.setCreateTime(LocalDateTime.now());
//}else {//本次添加的是套餐Long setmealId = shoppingCartDTO.getSetmealId();Setmeal setmeal = setmealMapper.getById(setmealId);shoppingCart.setName(setmeal.getName());shoppingCart.setImage(setmeal.getImage());shoppingCart.setAmount(setmeal.getPrice());
//                shoppingCart.setNumber(1);
//                shoppingCart.setCreateTime(LocalDateTime.now());}shoppingCart.setNumber(1);shoppingCart.setCreateTime(LocalDateTime.now());shoppingCartMapper.insert(shoppingCart);}}
}

四、查看购物车

4.1 需求分析和设计

4.2 代码开发

4.2.1Controller层

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

4.2.2 Service层

    /*** 查看购物车* @return*/@Overridepublic List<ShoppingCart> showShoppingCart() {//获取当前微信用户的idLong userId = BaseContext.getCurrentId();ShoppingCart shoppingCart = ShoppingCart.builder().userId(userId).build();List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);return list;}

五、清空购物车

5.1 需求分析和设计

5.2 代码开发

5.2.1 Controller层

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

5.2.2 Service层

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

5.2.3 Mapper层

    /*** 根据用户id删除购物车数据* @param userId*/@Delete("delete from shopping_cart where user_id =#{userId}")void deleteByUserId(Long userId);

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

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

相关文章

如何利用nginx在windows系统上搭建一个文件服务器

1&#xff1a;先下载windows版的nginx 官网 http://nginx.org/ 下载完后注意端口号&#xff08;默认端口号为&#xff1a;80&#xff09;是否被占用 启动nginx服务 地址为localhost的 如果出现 Welcome to nginx 就说明启动成功 2&#xff1a;然后进入conf文件里修改配置 …

题目:摆花(蓝桥OJ 0389)

问题描述&#xff1a; 题解&#xff1a; #include <bits/stdc.h> using namespace std; using ll long long; const int N 105; const ll p 1e6 7; ll a[N], dp[N][N];int main() {int n, m; cin >> n >> m;for(int i 1; i < n; i)cin >> a[i…

EdgeGallery开发指南

API接口 简介 EdgeGallery支持第三方业务系统通过北向接口网关调用EdgeGallery的业务接口。调用流程如下图所示&#xff08;融合前端edgegallery-fe包含融合前端界面以及北向接口网关功能&#xff0c;通过浏览器访问时打开的是融合前端的界面&#xff0c;通过IP:Port/urlPref…

网络原理(6)——IP协议

目录 一、网段划分 现在的网络划分&#xff1a; 1、一般情况下的家庭网络环境 2、IP地址 3、子网掩码 4、网关 以前的网络划分&#xff1a; 二、特殊IP 1、环回 IP 2、主机号为全 0 的IP 3、广播地址IP 三、路由选择&#xff08;路线规划&#xff09; 一、网段划分…

vue3+ts+element home页面侧边栏+头部组件+路由组件组合页面教程

文章目录 效果展示template代码script代码样式代码 效果展示 template代码 <template><el-container class"home"><el-aside class"flex" :style"{ width: asideDisplay ? 70px : 290px }"><div class"aside-left&q…

KubeSphere简单介绍及安装使用

KubeSphere 概述 官网地址&#xff1a;https://kubesphere.io/zh/ 什么是 kubesphere KubeSphere 是一个开源的多云容器管理平台&#xff0c;旨在简化企业级 k8s 集群的部署、管理和运维。它提供了一个可视化的管理界面&#xff0c;帮助用户更轻松地管理和监控 k8s 集群&…

vscode使用Runner插件将.exe文件统一放到一个目录下

找到右下角管理&#xff0c;点击扩展。 找到Code Runner插件&#xff0c;打开扩展设置。 向下翻&#xff0c;找到Executor Map&#xff0c;点击在settings.json中编辑。 在c和c的配置命令栏中增加\\\output\\即可。&#xff08;增加的目录不能自动创建&#xff0c;需要手动创建…

基于大语言模型的云故障根因分析|顶会EuroSys24论文

*马明华 微软主管研究员 2021年CCF国际AIOps挑战赛程序委员会主席&#xff08;第四届&#xff09; 2021年博士毕业于清华大学&#xff0c;2020年在佐治亚理工学院做访问学者。主要研究方向是智能运维&#xff08;AIOps&#xff09;、软件可靠性。近年来在ICSE、FSE、ATC、EuroS…

t-rex2开放集目标检测

论文链接&#xff1a;http://arxiv.org/abs/2403.14610v1 项目链接&#xff1a;https://github.com/IDEA-Research/T-Rex 这篇文章的工作是基于t-rex1的工作继续做的&#xff0c;核心亮点&#xff1a; 是支持图片/文本两种模态的prompt进行输入&#xff0c;甚至进一步利用两…

简单的SpringMVC项目创建流程(基于XML文件(了解))

1&#xff1a;首先创建一个maven项目&#xff0c;并在pom.xml文件中导入依赖 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 …

浅模仿小米商城布局(有微调)

CSS文件 *{margin: 0;padding: 0;box-sizing: border-box; }div[class^"h"]{height: 40px; } div[class^"s"]{height: 100px; } .h1{width: 1528px;background-color: green; } .h11{background-color:rgb(8, 220, 8); } .h111{width: 683px;background-c…

Linux 基础命令1

目录 一.Linux优点&#xff08;优势&#xff09; 二.Shell 三.Linux命令 四.help命令 五.Linux目录结构 六.目录操作 七.路径 一.Linux优点&#xff08;优势&#xff09; 1.一切都是一个文件 2.系统中拥有小型 &#xff0c;轻量级&#xff0c;单一用途的程序 3.避免令…

【循环神经网络rnn】一篇文章讲透

目录 引言 二、RNN的基本原理 代码事例 三、RNN的优化方法 1 长短期记忆网络&#xff08;LSTM&#xff09; 2 门控循环单元&#xff08;GRU&#xff09; 四、更多优化方法 1 选择合适的RNN结构 2 使用并行化技术 3 优化超参数 4 使用梯度裁剪 5 使用混合精度训练 …

MySQL高阶SQL语句

文章目录 MySQL高阶SQL语句MySQL常用查询1、按关键字排序1.1 语法1.2 ASC和DESC1.3 对数据表中信息进行排序1.3.1 普通排序1.3.2 结合where进行条件过滤1.3.3 对多个字段进行排序 2、区间判断及查询不重复记录2.1 and/or —— 且/或2.1.1 普通查询2.1.2 嵌套/多条件查询 2.2 di…

验证码demo(简单实现)

前言 我们注意到我们登录网站的时候经常会用到网络验证码,今天我们就简单实现一个验证码的前后端交互问题,做一个小demo 准备 我们这里并不需要依靠原生的java来实现,而是只需要引入一个maven依赖,使用现成的封装好的即可,这是我使用的是hutool工具包 网址:Hutool&#x1f36c;…

Linux 收发网络包的流程

应用层&#xff1a; 功能&#xff1a;提供应用程序间通信。例子&#xff1a;电子邮件客户端如Outlook或Thunderbird&#xff0c;它们提供用户界面来发送和接收电子邮件。这些客户端使用SMTP&#xff08;用于发送邮件&#xff09;和IMAP或POP3&#xff08;用于接收邮件&#xff…

计算机软件安全

一、软件安全涉及的范围 1.1软件本身的安全保密 软件的本质与特征&#xff1a; 可移植性 寄生性 再生性 可激发性 攻击性 破坏性 …… 知识产权与软件盗版 软件商品交易形式不透明&#xff0c;方式多样&#xff0c;传统商标标识方法不适用&#xff1b; 盗版方法简捷…

蓝桥杯刷题之路径之谜

题目来源 路径之谜 不愧是国赛的题目 题意 题目中会给你两个数组&#xff0c;我这里是分别用row和col来表示 每走一步&#xff0c;往左边和上边射一箭&#xff0c;走到终点的时候row数组和col数组中的值必须全部等于0这个注意哈&#xff0c;看题目看了半天&#xff0c;因为…

ASP.Net添加Swagger注释

文章目录 Swagger添加Swagger注释 Swagger 添加Swagger注释 1、右击项目->选择属性->点击生成->输出&#xff0c;选中文档文件 2、配置服务 在program.cs 文件里配置SwaggerUI //增加项一 builder.Services.AddSwaggerGen(c> {c.SwaggerDoc("v1", ne…

策略路由-IP-Link-路由协议简介

策略路由 策略路由和路由策略的不同 1.策略路由的操作对象是数据包&#xff0c;在路由表已经产生的情况下&#xff0c;不按照路由表进行转发&#xff0c;而是根据需要&#xff0c;依照某种策略改变数据包的转发路径 2.路由策略的操作对象是路由信息。路由策略的主要实现了路…