《苍穹外卖》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

相关文章

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

Mysql删除几亿条数据表中的部分数据的方法实现

《Mysql删除几亿条数据表中的部分数据的方法实现》在MySQL中删除一个大表中的数据时,需要特别注意操作的性能和对系统的影响,本文主要介绍了Mysql删除几亿条数据表中的部分数据的方法实现,具有一定... 目录1、需求2、方案1. 使用 DELETE 语句分批删除2. 使用 INPLACE ALTER T

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

Spring Boot中定时任务Cron表达式的终极指南最佳实践记录

《SpringBoot中定时任务Cron表达式的终极指南最佳实践记录》本文详细介绍了SpringBoot中定时任务的实现方法,特别是Cron表达式的使用技巧和高级用法,从基础语法到复杂场景,从快速启... 目录一、Cron表达式基础1.1 Cron表达式结构1.2 核心语法规则二、Spring Boot中定

国内环境搭建私有知识问答库踩坑记录(ollama+deepseek+ragflow)

《国内环境搭建私有知识问答库踩坑记录(ollama+deepseek+ragflow)》本文给大家利用deepseek模型搭建私有知识问答库的详细步骤和遇到的问题及解决办法,感兴趣的朋友一起看看吧... 目录1. 第1步大家在安装完ollama后,需要到系统环境变量中添加两个变量2. 第3步 “在cmd中

Spring Retry 实现乐观锁重试实践记录

《SpringRetry实现乐观锁重试实践记录》本文介绍了在秒杀商品SKU表中使用乐观锁和MybatisPlus配置乐观锁的方法,并分析了测试环境和生产环境的隔离级别对乐观锁的影响,通过简单验证,... 目录一、场景分析 二、简单验证 2.1、可重复读 2.2、读已提交 三、最佳实践 3.1、配置重试模板

在 Spring Boot 中使用异步线程时的 HttpServletRequest 复用问题记录

《在SpringBoot中使用异步线程时的HttpServletRequest复用问题记录》文章讨论了在SpringBoot中使用异步线程时,由于HttpServletRequest复用导致... 目录一、问题描述:异步线程操作导致请求复用时 Cookie 解析失败1. 场景背景2. 问题根源二、问题详细分

前端知识点之Javascript选择输入框confirm用法

《前端知识点之Javascript选择输入框confirm用法》:本文主要介绍JavaScript中的confirm方法的基本用法、功能特点、注意事项及常见用途,文中通过代码介绍的非常详细,对大家... 目录1. 基本用法2. 功能特点①阻塞行为:confirm 对话框会阻塞脚本的执行,直到用户作出选择。②