缓存商品、购物车(day07)

news2025/1/27 21:41:21

缓存菜品

问题说明

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

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

实现思路

通过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博客

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

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

相关文章

Langchain+讯飞星火大模型Spark Max调用

1、安装langchain #安装langchain环境 pip install langchain0.3.3 openai -i https://mirrors.aliyun.com/pypi/simple #灵积模型服务 pip install dashscope -i https://mirrors.aliyun.com/pypi/simple #安装第三方集成,就是各种大语言模型 pip install langchain-comm…

八股学习 微服务篇

微服务篇 常见面试内容Spring Cloud 常见组件注册中心Ribbon负载均衡策略服务雪崩 常见面试内容 Spring Cloud 常见组件 Spring Cloud有5个常见组件: Eureka/Nacos:注册中心;Ribbon:负载均衡;Feign:远程调用;Hystrix/Sentinel:服…

【xcode 16.2】升级xcode后mac端flutter版的sentry报错

sentry_flutter 7.11.0 报错 3 errors in SentryCrashMonitor_CPPException with the errors No type named terminate_handler in namespace std (line 60) and No member named set_terminate in namespace std 替换sentry_flutter版本为: 8.3.0 从而保证oc的…

electron打包客户端在rk3588上支持h265硬解

目录 前言 chromium是如何支持h265硬解 electron/chromium第一次编译 electron/chromium第二次编译 前言 我们的客户端程序是用electron打包的前端程序,其在rk3588主机上的linux环境运行。之前使用客户端查看h264编码的视频直播是没有问题的,但视频源…

基于物联网的风机故障检测装置的设计与实现

1 系统总体设计方案 通过对风机故障检测装置的设计与实现的需求、可行性进行分析,本设计风机故障检测装置的设计与实现的系统总体架构设计如图2-1所示,系统风机故障检测装置采用STM32F103单片机作为控制器,并通过DS18B20温度传感器、ACS712电…

为什么IDEA提示不推荐@Autowired❓️如果使用@Resource呢❓️

前言 在使用 Spring 框架时,依赖注入(DI)是一个非常重要的概念。通过注解,我们可以方便地将类的实例注入到其他类中,提升开发效率。Autowired又是被大家最为熟知的方式,但很多开发者在使用 IntelliJ IDEA …

软件工程的概论

软件的概念与特点 软件的定义 软件 程序 数据 文档 软件的特征 1。软件是人开发的 2。软件生产是简单的拷贝 3。软件会多次生产 4。软件开发环境对产品影响很大 5。 软件的双重作用 一方面是一种产品另一方面是开发其他软件产品的工具。 软件分类 按软件功能&…

1. 握手问题python解法——2024年省赛蓝桥杯真题

原题传送门:1.握手问题 - 蓝桥云课 问题描述 小蓝组织了一场算法交流会议,总共有 50人参加了本次会议。在会议上,大家进行了握手交流。按照惯例他们每个人都要与除自己以外的其他所有人进行一次握手 (且仅有一次)。但有 7 个人,…

【Uniapp-Vue3】setTabBar设置TabBar和下拉刷新API

一、setTabBar设置 uni.setTabBarItem({ index:"需要修改第几个", text:"修改后的文字内容" }) 二、tabBar的隐藏和显式 // 隐藏tabBar uni.hideTabBar(); // 显示tabBar uni.showTabBar(); 三、为tabBar右上角添加文本 uni.setTabBarBadge({ index:"…

Visual Studio Code修改terminal字体

个人博客地址:Visual Studio Code修改terminal字体 | 一张假钞的真实世界 默认打开中断后字体显示如下: 打开设置,搜索配置项terminal.integrated.fontFamily,修改配置为monospace。修改后效果如下:

使用ArcMap或ArcGIS Pro连接达梦数据库创建空间数据库

一、ArcMap 1、本地windows安装 32 位 DM 数据库客户端 2、覆盖dll 将 32 位 DM 数据的..\dmdbms\bin 目录中的 .dll 文件全部拷贝到 ArcGIS 的 ..\Desktop10.5\bin 目录下,有同名文件直接覆盖掉 3、开启达梦数据库空间扩展支持 使用管理员用户登录数据&#xff…

案例研究丨浪潮云洲通过DataEase推进多维度数据可视化建设

浪潮云洲工业互联网有限公司(以下简称为“浪潮云洲”)成立于2018年,定位于工业数字基础设施建设商、具有国际影响力的工业互联网平台运营商、生产性互联网头部服务商。截至目前,浪潮云洲工业互联网平台连续五年入选跨行业跨领域工…

ASP.NET Core 6.0 如何处理丢失的 Startup.cs 文件

介绍 .NET 6.0 已经发布,ASP.NET Core 6.0 也已发布。其中有不少变化让很多人感到困惑。例如,“谁动了我的奶酪”,它在哪里Startup.cs?在这篇文章中,我将深入研究这个问题,看看它移动到了哪里以及其他变化。…

iOS 集成ffmpeg

前言 本来打算用flutter去实现一个ffmpeg的项目的,不过仔细分析了一下,我后期需要集成OpenGL ES做视频渲染处理,OpenGL ES的使用目前在flutter上面还不是很成熟,所以最后还是选择用原生来开发 ffmpeg集成到iOS工程 iOS对于ffmp…

基于微信小程序的移动学习平台的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…

WPS计算机二级•幻灯片的基础操作

听说这是目录哦 PPT的正确制作步骤🛣️认识PPT界面布局🏜️PPT基础操作 快捷键🏞️制作PPT时 常用的快捷技巧🏙️快速替换PPT的 文本字体🌃快速替换PPT 指定文本内容🌅能量站😚 PPT的正确制作步…

Arcgis国产化替代:Bigemap Pro正式发布

在数字化时代,数据如同新时代的石油,蕴含着巨大的价值。从商业决策到科研探索,从城市规划到环境监测,海量数据的高效处理、精准分析与直观可视化,已成为各行业突破发展瓶颈、实现转型升级的关键所在。历经十年精心打磨…

GitLab配置免密登录和常用命令

SSH 免密登录 Windows免密登录 删除现有Key 访问目录:C:\Users\Administrator\ .ssh,删除公钥:id_rsa.pub ,私钥:id_rsa 2.生成.ssh 秘钥 运行命令生成.ssh 秘钥目录( ssh-keygen -t rsa -C xxxxxx126.…

警企联动齐发力、共筑反诈“防护墙”

2025年1月10日是第五个中国人民警察节,南通移动联合南通公安反诈中心,深入社区商圈,开展防范电信网络诈骗宣传活动,进一步增强广大人民群众的反诈意识和能力,全力守护好群众的“钱袋子”。 当日,活动现场一大早就呈现出一片忙碌景象,工作人员支起摊位,将各类精心制作的反诈宣传…

新版IDEA创建数据库表

这是老版本的IDEA创建数据库表,下面可以自己勾选Not null(非空),Auto inc(自增长),Unique(唯一标识)和Primary key(主键) 这是新版的IDEA创建数据库表,Not null和Auto inc可以看得到,但Unique和Primary key…