《苍穹外卖》Day07部分知识点记录

2024-04-27 23:52

本文主要是介绍《苍穹外卖》Day07部分知识点记录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、菜品缓存

减少查询数据库的次数,优化性能

客户端:

package com.sky.controller.user;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);}Dish dish = new Dish();dish.setCategoryId(categoryId);dish.setStatus(StatusConstant.ENABLE);//查询起售中的菜品// 如果不存在,查询数据库,将查询到的数据放入redis中list = dishService.listWithFlavor(dish);redisTemplate.opsForValue().set(key, list);return Result.success(list);}}

管理端:

package com.sky.controller.admin;import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.result.PageResult;
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.*;import java.util.List;
import java.util.Set;/*** 菜品管理*/
@RestController
@RequestMapping("/admin/dish")
@Api(tags = "菜品相关接口")
@Slf4j
public class DishController {@Autowiredprivate DishService dishService;@Autowiredprivate RedisTemplate redisTemplate;/*** 新增菜品* @param dishDTO* @return*/@PostMapping@ApiOperation("新增菜品")public Result save(@RequestBody DishDTO dishDTO) {log.info("新增菜品:{}", dishDTO);dishService.saveWithFlavor(dishDTO);// 清理缓存数据String key = "dish_" + dishDTO.getCategoryId();clearCache(key);return Result.success();}/*** 菜品分页查询* @param dishPageQueryDTO* @return*/@GetMapping("/page")@ApiOperation("菜品分页查询")public Result<PageResult> page(DishPageQueryDTO dishPageQueryDTO) {log.info("菜品分页查询:{}", dishPageQueryDTO);PageResult pageResult = dishService.pageQuery(dishPageQueryDTO);return Result.success(pageResult);}/*** 菜品批量删除* @param ids* @return*/@DeleteMapping@ApiOperation("菜品批量删除")public Result delete(@RequestParam List<Long> ids) {log.info("菜品批量删除:{}", ids);dishService.deleteBatch(ids);// 将所以的菜品缓存数据清除,所有以dish_开头的keyclearCache("dish_*");return Result.success();}/*** 根据id查询菜品* @param id* @return*/@GetMapping("/{id}")@ApiOperation("根据id查询菜品")public Result<DishVO> getById(@PathVariable Long id) {log.info("根据id查询菜品:{}", id);DishVO dishVO = dishService.getByIdWithFlavor(id);return Result.success(dishVO);}/*** 修改菜品* @param dishDTO* @return*/@PutMapping@ApiOperation("修改菜品")public Result update(@RequestBody DishDTO dishDTO) {log.info("修改菜品:{}", dishDTO);dishService.updateWithFlavor(dishDTO);// 将所以的菜品缓存数据清除,所有以dish_开头的keyclearCache("dish_*");return Result.success();}/*** 菜品起售停售* @param status* @param id* @return*/@PostMapping("/status/{status}")@ApiOperation("菜品起售停售")public Result<String> startOrStop(@PathVariable Integer status, Long id) {dishService.startOrStop(status, id);// 将所以的菜品缓存数据清除,所有以dish_开头的keyclearCache("dish_*");return Result.success();}/*** 根据分类id查询菜品* @param categoryId* @return*/@GetMapping("/list")@ApiOperation("根据分类id查询菜品")public Result<List<Dish>> list(Long categoryId) {List<Dish> list = dishService.list(categoryId);return Result.success(list);}/*** 清理缓存数据* @param pattern*/private void clearCache(String pattern) {Set keys = redisTemplate.keys(pattern);redisTemplate.delete(keys);}
}

二、Spring Cache

1. 概述

介绍

Spring Cache是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。

Spring Cache提供了一层抽象,底层可以切换不同的缓存实现,例如:

  • EHCache
  • Caffeine
  • Redis

常用注解

注解说明
@EnableCaching开启缓存注解功能,通常加在启动类上
@Cacheable在方法执行前先查询缓存中是否有数据,如果有数据,则直接返回缓存数据;如果没有缓存数据,调用方法并将方法返回值放到缓存中
@CachePut将方法的返回值放到缓存中
@CacheEvict将一条或多条数据从缓存中删除

2. 入门小案例

具体参见day07/springcache-demo项目

  • 导入Maven坐标
<!--        缓存--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId><version>2.7.3</version></dependency><!--        缓存中间件--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
  • 创建数据库
CREATE DATABASE IF NOT EXISTS spring_cache_demo;
USE 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`)
);
  • 修改配置文件里的数据库连接密码和redis连接密码以及使用的缓存数据库

  • 添加注解

①启动类

  • UserController——使用注解
package com.itheima.controller;import com.itheima.entity.User;
import com.itheima.mapper.UserMapper;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/user")
@Slf4j
@Api(tags = "用户相关接口")
public class UserController {@Autowiredprivate UserMapper userMapper;@PostMapping// 将方法的返回值放到缓存中// 如果使用Spring Cache缓存数据,key的生成:cacheNames::key@CachePut(cacheNames = "userCache", key = "#user.id")  // 从参数获取key// @CachePut(cacheNames = "userCache", key = "#result.id")  // 从返回值获取key// @CachePut(cacheNames = "userCache", key = "#p0.id")  // 从第一个参数获取// @CachePut(cacheNames = "userCache", key = "#a0.id")  // 从第一个参数获取// @CachePut(cacheNames = "userCache", key = "#root.args[0].id")  // 从第一个参数获取public User save(@RequestBody User user){userMapper.insert(user);return user;}@DeleteMapping@CacheEvict(cacheNames = "userCache", key = "#id")public void deleteById(Long id){userMapper.deleteById(id);}@DeleteMapping("/delAll")@CacheEvict(cacheNames = "userCache", allEntries = true)public void deleteAll(){userMapper.deleteAll();}@GetMapping@Cacheable(cacheNames = "userCache", key = "#id")public User getById(Long id){User user = userMapper.getById(id);return user;}}

3. spEL的简单介绍

SpEL(Spring Expression Language)是Spring框架中的表达式语言,用于在Spring应用程序中进行动态计算和引用。SpEL提供了一种类似于传统编程语言的表达式语法,可以在运行时对对象图进行访问和操作。

SpEL主要用于以下方面:

  • 在Spring配置文件中引用bean的属性值;
  • 在注解中引用bean的属性值;
  • 在Spring的注解驱动开发中进行条件判断和动态配置;
  • 在Spring Security中进行权限控制;
  • 在Spring Data中进行查询定义。

SpEL支持各种表达式操作,包括算术运算、逻辑运算、关系运算、正则表达式匹配、集合操作等。通过SpEL,可以使Spring应用程序更加灵活和动态,减少硬编码的情况,提高代码的的可维护性和可读性。

示例1:

@Value("#systemProperties['java.home']}")
private String javaHome;

在这个示例中,@Value注解中使用SpEL表达式#systemProperties['java.home']}来获取Java的安装路径,并将其赋值给javaHome变量。

示例2:

    @PostMapping// 将方法的返回值放到缓存中// 如果使用Spring Cache缓存数据,key的生成:cacheNames::key// @CachePut(cacheNames = "userCache", key = "#user.id")  // 从参数获取key// @CachePut(cacheNames = "userCache", key = "#result.id")  // 从返回值获取key// @CachePut(cacheNames = "userCache", key = "#p0.id")  // 从第一个参数获取// @CachePut(cacheNames = "userCache", key = "#a0.id")  // 从第一个参数获取@CachePut(cacheNames = "userCache", key = "#root.args[0].id")  // 从第一个参数获取public User save(@RequestBody User user){userMapper.insert(user);return user;}

三、作业代码——删除购物车中一个商品

1. ShoppingCartController

    /*** 删除购物车中一个商品* @param shoppingCartDTO* @return*/@PostMapping("/sub")@ApiOperation("删除购物车中一个商品")public Result sub(@RequestBody ShoppingCartDTO shoppingCartDTO) {log.info("删除购物车中一个商品,商品:{}", shoppingCartDTO);shoppingCartService.subShoppingCart(shoppingCartDTO);return Result.success();}

2. ShoppingCartService

    /*** 删除购物车中一个商品* @param shoppingCartDTO*/void subShoppingCart(ShoppingCartDTO shoppingCartDTO);

3. ShoppingCartServiceImpl

    /*** 删除购物车中一个商品* @param shoppingCartDTO*/@Overridepublic void subShoppingCart(ShoppingCartDTO shoppingCartDTO) {ShoppingCart shoppingCart = new ShoppingCart();BeanUtils.copyProperties(shoppingCartDTO, shoppingCart);// 设置查询条件,查询当前登录用户的购物车数据shoppingCart.setUserId(BaseContext.getCurrentId());List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);if(list != null && list.size() > 0) {shoppingCart = list.get(0);Integer number = shoppingCart.getNumber();if(number == 1) {// 当前商品在购物车中的份数为1,直接删除当前记录shoppingCartMapper.deleteById(shoppingCart.getId());} else {// 当前商品在购物车中的份数不为1,修改份数即可shoppingCart.setNumber(shoppingCart.getNumber() - 1);shoppingCartMapper.updateNumberById(shoppingCart);}}

4. ShoppingCartMapper

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

这篇关于《苍穹外卖》Day07部分知识点记录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Python UV安装、升级、卸载详细步骤记录

《PythonUV安装、升级、卸载详细步骤记录》:本文主要介绍PythonUV安装、升级、卸载的详细步骤,uv是Astral推出的下一代Python包与项目管理器,主打单一可执行文件、极致性能... 目录安装检查升级设置自动补全卸载UV 命令总结 官方文档详见:https://docs.astral.sh/

统一返回JsonResult踩坑的记录

《统一返回JsonResult踩坑的记录》:本文主要介绍统一返回JsonResult踩坑的记录,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录统一返回jsonResult踩坑定义了一个统一返回类在使用时,JsonResult没有get/set方法时响应总结统一返回

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

java对接海康摄像头的完整步骤记录

《java对接海康摄像头的完整步骤记录》在Java中调用海康威视摄像头通常需要使用海康威视提供的SDK,下面这篇文章主要给大家介绍了关于java对接海康摄像头的完整步骤,文中通过代码介绍的非常详细,需... 目录一、开发环境准备二、实现Java调用设备接口(一)加载动态链接库(二)结构体、接口重定义1.类型

apache的commons-pool2原理与使用实践记录

《apache的commons-pool2原理与使用实践记录》ApacheCommonsPool2是一个高效的对象池化框架,通过复用昂贵资源(如数据库连接、线程、网络连接)优化系统性能,这篇文章主... 目录一、核心原理与组件二、使用步骤详解(以数据库连接池为例)三、高级配置与优化四、典型应用场景五、注意事

SpringBoot实现文件记录日志及日志文件自动归档和压缩

《SpringBoot实现文件记录日志及日志文件自动归档和压缩》Logback是Java日志框架,通过Logger收集日志并经Appender输出至控制台、文件等,SpringBoot配置logbac... 目录1、什么是Logback2、SpringBoot实现文件记录日志,日志文件自动归档和压缩2.1、

qtcreater配置opencv遇到的坑及实践记录

《qtcreater配置opencv遇到的坑及实践记录》我配置opencv不管是按照网上的教程还是deepseek发现都有些问题,下面是我的配置方法以及实践成功的心得,感兴趣的朋友跟随小编一起看看吧... 目录电脑环境下载环境变量配置qmake加入外部库测试配置我配置opencv不管是按照网上的教程还是de

使用nohup和--remove-source-files在后台运行rsync并记录日志方式

《使用nohup和--remove-source-files在后台运行rsync并记录日志方式》:本文主要介绍使用nohup和--remove-source-files在后台运行rsync并记录日... 目录一、什么是 --remove-source-files?二、示例命令三、命令详解1. nohup2.

Java使用SLF4J记录不同级别日志的示例详解

《Java使用SLF4J记录不同级别日志的示例详解》SLF4J是一个简单的日志门面,它允许在运行时选择不同的日志实现,这篇文章主要为大家详细介绍了如何使用SLF4J记录不同级别日志,感兴趣的可以了解下... 目录一、SLF4J简介二、添加依赖三、配置Logback四、记录不同级别的日志五、总结一、SLF4J

一文详解如何在Python中从字符串中提取部分内容

《一文详解如何在Python中从字符串中提取部分内容》:本文主要介绍如何在Python中从字符串中提取部分内容的相关资料,包括使用正则表达式、Pyparsing库、AST(抽象语法树)、字符串操作... 目录前言解决方案方法一:使用正则表达式方法二:使用 Pyparsing方法三:使用 AST方法四:使用字