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

news2024/5/18 16:13:28

一、菜品缓存

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

客户端:

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 {
    @Autowired
    private DishService dishService;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 根据分类id查询菜品
     *
     * @param categoryId
     * @return
     */
    @GetMapping("/list")
    @ApiOperation("根据分类id查询菜品")
    public Result<List<DishVO>> list(Long categoryId) {
        // 构造redis中的key,规则:dish_分类id
        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);//查询起售中的菜品

        // 如果不存在,查询数据库,将查询到的数据放入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 {
    @Autowired
    private DishService dishService;
    @Autowired
    private 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_开头的key
        clearCache("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_开头的key
        clearCache("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_开头的key
        clearCache("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 {

    @Autowired
    private 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
     */
    @Override
    public 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);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1622060.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用微软Phi-3-mini模型快速创建生成式AI应用

微软Phi-3大语言模型是微软研究院推出的新一代系列先进的小语言模型。Phi-3系列包括phi-3-mini、phi-3-small和phi-3-medium三个不同规模的版本。这些模型在保持较小的参数规模的同时&#xff0c;通过精心设计的训练数据集和优化的算法&#xff0c;实现了与大型模型相媲美的语言…

软件测试之【软件测试概论三】

读者大大们好呀&#xff01;&#xff01;!☀️☀️☀️ &#x1f525; 欢迎来到我的博客 &#x1f440;期待大大的关注哦❗️❗️❗️ &#x1f680;欢迎收看我的主页文章➡️寻至善的主页 文章目录 前言测试用例的前因后果测试用例的设计方法黑盒测试用例设计方法&#x1f525…

JavaEE 初阶篇-深入了解 I/O 流(FileInputStream 与 FileOutputStream 、Reader 与 Writer)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 I/O 流概述 2.0 文件字节输入流(FileInputStream) 2.1 创建 FileInputStream 对象 2.2 读取数据 2.3 关闭流 3.0 文件字节输出流(FileOutputStream) 3.1 创建 Fi…

html、css、QQ音乐移动端静态页面,资源免费分享,可作为参考,提供InsCode在线运行演示

CSDN将我上传的免费资源私自变成VIP专享资源&#xff0c;且作为作者的我不可修改为免费资源&#xff0c;不可删除&#xff0c;寻找客服无果&#xff0c;很愤怒&#xff0c;&#xff08;我发布免费资源就是希望大家能免费一起用、一起学习&#xff09;&#xff0c;接下来继续寻找…

智慧医院解决方案

5G智慧导航解决方案https://www.cgltzk.vip/doc/1537/ 深圳市妇幼保健院妇产科住院大楼智能化系统招标文件(技术规格书)https://www.cgltzk.vip/doc/1534/ 三甲医院智能化系统设计方案https://www.cgltzk.vip/doc/1423/ 医院智能化设计方案https://www.cgltzk.vip/doc/1422/ …

矩阵按列相乘运算的并行化实现方法

这两天一直在琢磨如下矩阵计算问题。 已知dm矩阵X和hq矩阵Y&#xff0c;求如下矩阵&#xff1a; 其中X(:,i), Y(:,j)分别表示矩阵X, Y的第i列和第j列&#xff0c;易知Z为dh矩阵。 如果直接串行计算矩阵Z&#xff0c;两个循环共有mq&#xff0c;则会很慢&#xff0c;能不能并行化…

UE5 GAS开发P34 游戏效果理论

GameplayEffects Attributes&#xff08;属性&#xff09;和Gameplay Tags&#xff08;游戏标签&#xff09;分别代表游戏中实体的特性和标识。 Attributes&#xff08;属性&#xff09;&#xff1a;Attributes是用来表示游戏中实体的特性或属性的值&#xff0c;例如生命值、…

Ant Design Vue + js 表格计算合计

1.需要计算的数量固定&#xff08;如表1&#xff0c;已知需要计算的金额为&#xff1a;装修履约保证金 装修垃圾清运费出入证工本费 出入证押金 这四项相加&#xff0c;可以写成固定的算法&#xff09;&#xff1a; 表格样式&#xff1a; <h4 style"margin: 0 0 8px…

【数据结构】图(Graph)

文章目录 概念图的存储方式邻接矩阵邻接矩阵表示法邻接矩阵表示法的特点 邻接表邻接表表示法邻接表表示法的特点邻接表表示法的定义与实现查找插入删除其它构造函数析构函数创建图输出图 图的遍历深度优先遍历&#xff08;DFS&#xff09;广度优先遍历 图的连接分量和生成树生成…

Xilinx 7系列MMCM/PLL的使用模型

本文展示了MMCM的一些使用模型&#xff08;同样适用于PLL&#xff09;&#xff0c;如时钟网络去偏斜、具有内部反馈的MMCM和零延迟缓冲区等。 1、时钟网络去偏斜&#xff08;Clock Network Deskew&#xff09; MMCM的主要用途之一是用于时钟网络去偏斜。图3-11和图3-12展示了…

【2024年最新】NodeMCU-ESP8266刷AT固件教程——适用于esp-12E和esp-12F

硬件图片 原理图 0、工具打包下载 工具包 密码:keduo 1、工具及固件下载 固件下载地址&#xff1a; 欢迎 | 安信可科技 (ai-thinker.com) 下载以下固件&#xff1a; 直接下载地址&#xff1a;AT 固件&#xff08;固件号&#xff1a;0781&#xff09; 下载以下工具&#xf…

【SQL代理中转注入】对DVWA登录界面username字段实施注入

一、实验过程 步骤0&#xff1a;注释掉相关username防护&#xff0c;截图如下&#xff1a; 以DVWA为攻击目标&#xff0c;将login.php中第21、22行注释掉 步骤1&#xff1a;源码分析&#xff0c;截图如下&#xff1a; 如此可知&#xff0c;首先需要通过token验证&#xff0c;然…

LeetCode90:子集②

题目描述 给你一个整数数组 nums &#xff0c;其中可能包含重复元素&#xff0c;请你返回该数组所有可能的 子集 &#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。返回的解集中&#xff0c;子集可以按 任意顺序 排列。 解题思想 要考虑去重的操作 代码 class Sol…

【java、微服务】MQ

MQ(MessageQueue)&#xff0c;中文是消息队列&#xff0c;字面来看就是存放消息的队列。也就是事件驱动架构中的Broker。 同步通讯 优点 时效性较强&#xff0c;可以立即得到结果 问题 微服务间基于Feign的调用就属于同步方式&#xff0c;存在一些问题。 耦合度高。每次加…

Shader for Quest 2: 自定义shader在Unity Editor中可以使用,但是在Quest 2中却不可以

GameObject segment GameObject.Find("DisplayArea_" i); MeshRenderer renderer segment.GetComponent<MeshRenderer>(); Material mat new Material(Shader.Find("Custom/MyShader")); mat.mainTexture option.Image360;上面这份代码&#x…

嵌入式Linux driver开发实操(二十一):linux device driver basic设备驱动程序基础

linux的架构框图: 内核空间是内核(即操作系统的核心)执行(即运行)并提供其服务的地方。 用户空间是执行用户应用程序的地方。 内核模块是可以根据需要加载和卸载到内核中的代码片段。它们扩展了内核的功能,而无需重新启动系统。自定义代码可以通过两种方法添加到Linux内…

SpringMVC基础篇(一)

文章目录 1.基本介绍1.特点2.SpringMVC跟SpringBoot的关系 2.快速入门1.需求分析2.图解3.环境搭建1.创建普通java工程2.添加web框架支持3.配置lib文件夹1.导入jar包2.Add as Library3.以后自动添加 4.配置tomcat1.配置上下文路径2.配置热加载 5.src下创建Spring配置文件applica…

BUUCTF-MISC-09文件中的秘密1

9.文件中的秘密1 题目&#xff1a;flag包含在图片的属性中

三款数据可视化工具深度解析:Tableau、ECharts与山海鲸可视化

在数字化时代&#xff0c;数据可视化工具成为了企业和个人进行数据分析和决策的重要助手。市面上众多数据可视化工具各具特色&#xff0c;本文将为您介绍三款热门的数据可视化工具&#xff0c;帮助您更好地理解和利用数据。 首先&#xff0c;让我们来认识Tableau。Tableau是一款…

基于python+django+mysql农业生产可视化系统

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…