缓存商品、购物车(day07)

缓存菜品

问题说明

问题说明:用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大。

结果: 系统响应慢、用户体验差

实现思路

通过Redis来缓存菜品数据,减少数据库查询操作。

缓存逻辑分析:

  • 每个分类下的菜品保存一份缓存数据
  • 数据库中菜品数据有变更时清理缓存数据

代码开发

修改用户端接口 DishController list 方法,加入缓存处理逻辑:

为了保证数据库Redis中的数据保持一致,修改管理端接口 DishController 的相关方法,加入清理缓存逻辑。

修改管理端接口 DishController 的相关方法,加入清理缓存的逻辑,需要改造的方法:

  • 新增菜品
  • 修改菜品
  • 批量删除菜品
  • 起售、停售菜品

抽取清理缓存的方法:

调用清理缓存的方法,保证数据一致性:

调用清理缓存的方法,保证数据一致性:

调用清理缓存的方法,保证数据一致性:

功能测试

可以通过如下方式进行测试:

查看控制台 sql
前后端联调
查看 Redis 中的缓存数据

缓存套餐

Spring Cache

介绍

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

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

  • EHCache
  • Caffeine
  • Redis(常用)

常用注解:

在 SpringCache 中提供了很多缓存操作的注解,常见的是以下的几个:

在spring boot项目中,使用缓存技术只需在项目中导入相关缓存技术的依赖包,并在启动类上使用@EnableCaching开启缓存支持即可。

例如,使用Redis作为缓存技术,只需要导入Spring data Redis的maven坐标即可。

入门案例

入门案例:导入资料中的初始工程,在此基础上加入Spring Cache注解即可

导入基础工程: 底层已使用 Redis 缓存实现
基础环境的代码,在我们今天的资料中已经准备好了, 大家只需要将这个工程导入进来就可以了。导入进来的工程结构如下:

数据库准备:
创建名为spring_cache_demo数据库,将springcachedemo.sql脚本直接导入数据库中。

1、引导类上加@EnableCaching:
package com.itheima;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@Slf4j
@SpringBootApplication
@EnableCaching //开启缓存注解功能
public class CacheDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(CacheDemoApplication.class,args);
        log.info("项目启动成功...");
    }
}
2). @CachePut注解

@CachePut 说明:

  • ​作用: 将方法返回值,放入缓存
  • value: 缓存的名称, 每个缓存名称下面可以有很多key
  • key: 缓存的key ----------> 支持Spring的表达式语言SPEL语法

在save方法上加注解@CachePut
当前 UserController 的 save 方法是用来保存用户信息的,我们希望在该用户信息保存到数据库的同时,也往缓存中缓存一份数据,我们可以在 save 方法上加上注解 @CachePut,用法如下:

/**
     * CachePut:将方法返回值放入缓存
     * value:缓存的名称,每个缓存名称下面可以有多个key
     * key:缓存的key
     */
    @PostMapping
    @CachePut(cacheNames = "userCache",key = "#user.id") //如果使用Spring Cache缓存数据,key的生成:userCache::1
    //@CachePut(cacheNames = "userCache",key = "#result.id") //对象导航
    //@CachePut(value = "userCache", key = "#p0.id")//p0,第一个参数;p1,第二个参数
    //@CachePut(value = "userCache", key = "#a0.id")//a0,第一个参数;a1,第二个参数
    //@CachePut(value = "userCache", key = "#root.args[0].id")//root.args[0],第一个参数
    public User save(@RequestBody User user){
        userMapper.insert(user);
        return user;
    }

说明: key的写法如下

  1. #user.id : #user指的是方法形参的名称, id指的是user的id属性 , 也就是使用user的id属性作为key ;
  2. #result.id : #result代表方法返回值,该表达式 代表以返回对象的id属性作为key ;
  3. #p0.id:#p0指的是方法中的第一个参数,id指的是第一个参数的id属性,也就是使用第一个参数的id属性作为key ;
  4. #a0.id:#a0指的是方法中的第一个参数,id指的是第一个参数的id属性,也就是使用第一个参数的id属性作为key ;
  5. #root.args[0].id:#root.args[0]指的是方法中的第一个参数,id指的是第一个参数的id属性,也就是使用第一个参数的id属性作为key ;

启动服务,通过swagger接口文档测试,访问UserController的save()方法 

3). @Cacheable注解

@Cacheable 说明:

  • ​ 作用: 在方法执行前,spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中
  • ​​ value: 缓存的名称,每个缓存名称下面可以有多个key
  • ​​ key: 缓存的key ----------> 支持Spring的表达式语言SPEL语法

在getById上加注解@Cacheable

/**
     * Cacheable:在方法执行前spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,	  *调用方法并将方法返回值放到缓存中
     * value:缓存的名称,每个缓存名称下面可以有多个key
     * key:缓存的key
     */
    @Cacheable(cacheNames = "userCache",key = "#id")
    @GetMapping
    public User getById(Long id){
        User user = userMapper.getById(id);
        return user;
    }

重启服务,通过swagger接口文档测试,访问UserController的getById()方法
第一次访问,会请求我们controller的方法,查询数据库。后面再查询相同的id,就直接从Redis中查询数据,不用再查询数据库了,就说明缓存生效了。

4). @CacheEvict注解

@CacheEvict 说明:

  • ​ 作用: 清理指定缓存
  • ​ value: 缓存的名称,每个缓存名称下面可以有多个key
  • ​ key: 缓存的key ----------> 支持Spring的表达式语言SPEL语法

在 delete 方法上加注解@CacheEvict

@CacheEvict(cacheNames = "userCache",key = "#id")//删除某个key对应的缓存数据
    @DeleteMapping
    public void deleteById(Long id){
        userMapper.deleteById(id);
    }

    @CacheEvict(cacheNames = "userCache",allEntries = true)//删除userCache下所有的缓存数据
	@DeleteMapping("/delAll")
    public void deleteAll(){
        userMapper.deleteAll();
    }

重启服务,通过swagger接口文档测试,访问UserController的deleteAll()方法

实现思路

实现步骤:

  1. 导入Spring Cache和Redis相关maven坐标
  2. 在启动类上加入@EnableCaching注解,开启缓存注解功能
  3. 在用户端接口SetmealController的 list 方法上加入@Cacheable注解
  4. 在管理端接口SetmealController的 save、delete、update、startOrStop等方法上加入CacheEvict注解

代码开发

1). 导入Spring Cache和Redis相关maven坐标(已实现)

2). 在启动类上加入@EnableCaching注解,开启缓存注解功能

3). 在用户端接口SetmealController的 list 方法上加入@Cacheable注解

4).管理端接口SetmealControllersavedeleteupdatestartOrStop等方法上加入CacheEvict注解:

功能测试

添加购物车

需求分析和设计

产品原型:
 

接口设计:

请求方式:POST
请求路径:/user/shoppingCart/add
请求参数:套餐 id 、菜品 id 、口味
返回结果: code data msg

数据库设计:

作用:暂时存放所选商品的地方
选的什么商品
每个商品都买了几个
不同用户的购物车需要区分开

用户的购物车数据,也是需要保存在数据库中的,购物车对应的数据表为 shopping_cart 表,具体表结构如下:

说明:

  • 购物车数据是关联用户的,在表结构中,我们需要记录,每一个用户的购物车数据是哪些
  • 菜品列表展示出来的既有套餐,又有菜品,如果用户选择的是套餐,就保存套餐ID(setmeal_id),如果用户选择的是菜品,就保存菜品ID(dish_id)
  • 对同一个菜品/套餐,如果选择多份不需要添加多条记录,增加数量number即可

代码开发

根据添加购物车接口的参数设计DTO:

根据添加购物车接口创建ShoppingCartController:

创建ShoppingCartService接口:

创建ShoppingCartServiceImpl实现类,并实现add方法:

创建ShoppingCartServiceImpl实现类,并实现add方法:

创建ShoppingCartMapper接口:

创建ShoppingCartMapper.xml:

功能测试

查看购物车

需求分析和设计

产品原型:

接口设计:

代码开发

ShoppingCartController中创建查看购物车的方法:

ShoppingCartService接口中声明查看购物车的方法:

ShoppingCartServiceImpl中实现查看购物车的方法:

功能测试

清空购物车

需求分析和设计

产品原型:

接口设计:

代码开发

ShoppingCartController中创建清空购物车的方法:

ShoppingCartService接口中声明清空购物车的方法:

ShoppingCartServiceImpl中实现清空购物车的方法:

ShoppingCartMapper接口中创建删除购物车数据的方法:

功能测试

上一节:

商品浏览(day06)下-CSDN博客

下一节:

地址簿功能代码(day08上)-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构测试题2

一、单选题(每题 2 分,共20分) 1. 栈和队列的共同特点是( A )。 A.只允许在端点处插入和删除元素 B.都是先进后出 C.都是先进先出 D.没有共同点 2. 用链接方式存储的队列,在进行插入运算时( C ) A. 仅修改头指针 B. 头…

qml Settings详解

1、概述 QML中的Settings类提供了一种便捷的方式来保存和恢复应用程序的配置信息,如用户名、密码、窗口位置和大小等。它简化了配置数据的存储过程,无需使用像SQLite这样的数据库系统。通过使用Settings,开发者可以轻松实现应用程序设置的持…

认识Django项目模版文件——Django学习日志(二)

1.默认文件介绍 └── djangoproject1/├── djangoproject1/│ ├── urls.py [URL和函数的对应关系]【常用文件】│ ├── settings.py [项目配置文件]【常用文件】│ ├── _init_.py│ ├── wsgi.py [接受网络请求] 【不要动】│ └──…

Qt实践:一个简单的丝滑侧滑栏实现

Qt实践:一个简单的丝滑侧滑栏实现 笔者前段时间突然看到了侧滑栏,觉得这个抽屉式的侧滑栏非常的有趣,打算这里首先尝试实现一个简单的丝滑侧滑栏。 首先是上效果图 (C,GIF帧率砍到毛都不剩了) QProperty…

【Linux网络编程】传输层协议

目录 一,传输层的介绍 二,UDP协议 2-1,UDP的特点 2-2,UDP协议端格式 三,TCP协议 3-1,TCP报文格式 3-2,TCP三次握手 3-3,TCP四次挥手 3-4,滑动窗口 3-5&#xf…

[C]基础8.详解操作符

博客主页:算法歌者本篇专栏:[C]您的支持,是我的创作动力。 文章目录 0、总结1、操作符的分类2、二进制和进制转换2.1、2进制转10进制2.2、10进制转2进制2.3、2进制转8进制和16进制 3、原码、反码、补码4、移位操作符4.1 左移操作符4.2 右移操…

基于Springboot用axiospost请求接收字符串参数为null的解决方案

问题 ​ 今天在用前端 post 请求后端时发现,由于是以 Json对象的形式传输的,后端用两个字符串形参无法获取到对应的参数值 前端代码如下: axios.post(http://localhost:8083/test/postParams,{a: 1, b:2} ,{Content-Type: application/jso…

数据结构——堆(介绍,堆的基本操作、堆排序)

我是一个计算机专业研0的学生卡蒙Camel🐫🐫🐫(刚保研) 记录每天学习过程(主要学习Java、python、人工智能),总结知识点(内容来自:自我总结网上借鉴&#xff0…

【Qt】05-菜单栏

做菜单 前言一、创建文件二、菜单栏 QMenuBar2.1 示例代码2.2 运行结果 三、工具栏 QToolBar3.1 运行代码3.2 结果分析 四、状态栏 QStatusBar4.1 运行代码4.2 运行结果 五、文本编辑框 QTextEdit5.1 运行代码5.2 运行结果 六、浮动窗口 addDockWidget6.1 运行代码6.2 运行结果…

【喜讯】海云安荣获“数字安全产业贡献奖”

近日,国内领先的数字化领域独立第三方调研咨询机构数世咨询主办的“2025数字安全市场年度大会”在北京成功举办。在此次大会上,海云安的高敏捷信创白盒产品凭借其在AI大模型技术方面的卓越贡献和突出的技术创新能力,荣获了“数字安全产业贡献…

MySQL训练营-慢查询诊断问题

slow_query_log long_query_time slow_query_log:日志开关,是否记慢查询日志 long_query_time:超过多长时间判定为慢查询 查看参数设置: SHOW VARIABLES LIKE ‘slow_query_log’;SHOW VARIABLES LIKE ‘long_query_time’; …

2025年最新汽车零部件企业销售项目管理解决方案

在汽车零部件企业,销售项目管理的不规范和销售预测的不准确性常导致生产计划无法及时调整,因此客户关系常常中断,导致企业业务机会的丧失。为解决该问题,企业需要投入更多资源以优化销售流程与销售预测。 1、360多维立体客户视图…

K8S中ingress详解

Ingress介绍 Kubernetes 集群中,服务(Service)是一种抽象,它定义了一种访问 Pod 的方式,无论这些 Pod 如何变化,服务都保持不变。服务可以被映射到一个静态的 IP 地址(ClusterIP)、一…

大模型:LangChain技术讲解

一、什么是LangChain 1、介绍 LangChain是一个用于开发由大型语言模型提供支持的Python框架。它提供了一系列工具和组件,帮助我们将语言模型集成到自己的应用程序中。 有了它之后,我们可以更轻松地实现对话系统、文本生成、文本分类、问答系统等功能。…

【优选算法篇】2----复写零

---------------------------------------begin--------------------------------------- 这道算法题相对于移动零,就上了一点点强度咯,不过还是很容易理解的啦~ 题目解析: 这道题如果没理解好题目,是很难的,但理解题…

office 2019 关闭word窗口后卡死未响应

最近关闭word文件总是出现卡死未响应的状态,必须从任务管理器才能杀掉word 进程,然后重新打开word再保存,很是麻烦。(#其他特征,在word中打字会特别变慢,敲击键盘半秒才出现字符。) office官网…

acm培训 part 1(学习总结)

第一部分的重点为语法糖,时空复杂度,stl容器等等,下面就简单介绍一下这些部分。 1. 语法糖 1.1 定义 语法糖是由英国计算机科学家彼得约翰兰达提出的一个术语,指的是编程语言中添加的某种语法,这种语法对语言的功能…

Arduino基础入门学习——OLED显示屏+DHT11采集温湿度并显示

Arduino基础入门学习——OLED显示屏DHT11显示温湿度 一、前言二、准备工作三、程序代码四、结束语 一、前言 本篇文章主要使用OLED液晶显示屏模块和DHT11温湿度传感器,获取环境温湿度并显示在显示屏,也算是结合之前我所编写的博客给大家带来一个算是比较…

Kubernetes相关知识入门详解

一、Pod的滚动升级 1.服务升级的一般思路:停止与该服务相关的所有服务pod,重新拉去更新后的镜像并启动。这种方法存在一个比较现实的问题是逐步升级导致较长时间的服务不可用。 2.Kubernetes滚动升级的思路:通过滚动升级的命令创建新的rc&…

云原生时代,如何构建高效分布式监控系统

文章目录 一.监控现状二.Thanos原理分析SidecarQuerierStoreCompactor 三.Sidecar or ReceiverThanos Receiver工作原理 四.分布式运维架构 一.监控现状 Prometheus是CNCF基金会管理的一个开源监控项目,由于其良好的架构设计和完善的生态,迅速成为了监控…