黑马苍穹外卖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中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash

MyBatis延迟加载与多级缓存全解析

《MyBatis延迟加载与多级缓存全解析》文章介绍MyBatis的延迟加载与多级缓存机制,延迟加载按需加载关联数据提升性能,一级缓存会话级默认开启,二级缓存工厂级支持跨会话共享,增删改操作会清空对应缓... 目录MyBATis延迟加载策略一对多示例一对多示例MyBatis框架的缓存一级缓存二级缓存MyBat