黑马苍穹外卖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 NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

Java注解之超越Javadoc的元数据利器详解

《Java注解之超越Javadoc的元数据利器详解》本文将深入探讨Java注解的定义、类型、内置注解、自定义注解、保留策略、实际应用场景及最佳实践,无论是初学者还是资深开发者,都能通过本文了解如何利用... 目录什么是注解?注解的类型内置注编程解自定义注解注解的保留策略实际用例最佳实践总结在 Java 编程

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

redis中使用lua脚本的原理与基本使用详解

《redis中使用lua脚本的原理与基本使用详解》在Redis中使用Lua脚本可以实现原子性操作、减少网络开销以及提高执行效率,下面小编就来和大家详细介绍一下在redis中使用lua脚本的原理... 目录Redis 执行 Lua 脚本的原理基本使用方法使用EVAL命令执行 Lua 脚本使用EVALSHA命令

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows