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

本文主要是介绍黑马苍穹外卖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);}

这篇关于黑马苍穹外卖6 清理redis缓存+Spring Cache+购物车的增删改查的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1087787

相关文章

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

Redis 的 SUBSCRIBE命令详解

《Redis的SUBSCRIBE命令详解》Redis的SUBSCRIBE命令用于订阅一个或多个频道,以便接收发送到这些频道的消息,本文给大家介绍Redis的SUBSCRIBE命令,感兴趣的朋友跟随... 目录基本语法工作原理示例消息格式相关命令python 示例Redis 的 SUBSCRIBE 命令用于订

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

JavaScript中的高级调试方法全攻略指南

《JavaScript中的高级调试方法全攻略指南》什么是高级JavaScript调试技巧,它比console.log有何优势,如何使用断点调试定位问题,通过本文,我们将深入解答这些问题,带您从理论到实... 目录观点与案例结合观点1观点2观点3观点4观点5高级调试技巧详解实战案例断点调试:定位变量错误性能分

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志