当前位置: 首页 > news >正文

03黑马店评-添加商户缓存和商户类型的缓存到Redis

商户查询缓存

什么是缓存

实际开发过程中数据量可以达到几千万,缓存可以作为避震器防止过高的数据访问猛冲系统,避免系统内的操作线程无法及时处理信息而瘫痪

缓存(Cache)就是数据交换的缓冲区(储存临时数据的地方),我们俗称的"缓存"实际就是缓冲区内的数据(一般从数据库中获取存储于本地)

  • Static修饰: 随着类的加载而被加载到内存之中从而作为本地缓存
  • final修饰: 其引用和对象之间的关系是固定的不能改变,因此不用担心赋值时导致缓存失效
// 本地用于高并发
Static final ConcurrentHashMap<K,V> map = new ConcurrentHashMap<>(); // 用于redis等缓存
static final Cache<K,V> USER_CACHE = CacheBuilder.newBuilder().build(); // 本地缓存
Static final Map<K,V> map =  new HashMap(); 

缓存的优点和缺点

  • 优点: 缓存数据存储于代码中而代码又运行在内存中(读写性能远高于磁盘),从而大大降低用户访问的并发量给服务器带来的读写压力
  • 缺点: 需要维护原数据和缓存数据一致性,这就需要增加代码复杂度(维护起来比较麻烦)和运维成本(缓存需要搭建集群模式)

实际开发中,会构筑多级缓存来使系统运行速度进一步提升,如本地缓存与Redis中的缓存并发使用

  • 浏览器缓存: 主要是存在于浏览器端的缓存(css文件和js文件等静态资源)
  • 应用层缓存: 可以分为tomcat本地缓存,比如使用map集合或者redis作为缓存
  • 数据库缓存: 在数据库中有一片空间是buffer pool(缓存索引),增改查的数据都会先加载到mysql的缓存中
  • CPU缓存: 当代计算机最大的问题是cpu性能提升了,但内存读写速度没有跟上,所以为了适应当下的情况,增加了cpu的L1,L2,L3级的缓存

在这里插入图片描述

添加商户缓存

在Service层创建queryById方法, 然后在ServiceImpl中重写该方法,在Controller中调用该方法

当我们使用浏览器发送请求访问一个商户信息时如果直接从数据库中查询商户信息效率很慢,所以一般在客户端与数据库之间加上一个Redis缓存

@GetMapping("/{id}")
public Result queryShopById(@PathVariable("id") Long id) {// 这里是直接调用Mybaits-Plus提供的方法查询数据库return shopService.queryById(id);
}

在这里插入图片描述

重启服务器访问商户信息,观察控制台日志输出然后刷新页面, 控制台不会出现查询商户信息的SQL语句,在Redis图形化界面中也可以看到缓存的商户信息数据

// Redis中缓存店铺的key前缀
public static final String CACHE_SHOP_KEY = "cache:shop:";
@GetMapping("/{id}")
public Result queryShopById(@PathVariable("id") Long id) {// 先从Redis中查询店铺数据,如果缓存里有数据直接返回,如果缓存中没有则去查询数据库并存入Redisreturn shopService.queryById(id);
}
public interface IShopService extends IService<Shop> {Result queryById(Long id);
}
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Overridepublic Result queryById(Long id) {// 先从Redis中查询对应的店铺缓存信息,这里的key是店铺固定的前缀+查询的店铺idString shopJson = stringRedisTemplate.opsForValue().get(CACHE_SHOP_KEY + id);// 如果在Redis中查询到了店铺信息(String类型的JSON字符串)则转为Shop类型直接返回if (StrUtil.isNotBlank(shopJson)) {Shop shop = JSONUtil.toBean(shopJson, Shop.class);return Result.ok(shop);}// 在Redis中没查询到店铺信息则根据店铺Id去数据库中查Shop shop = getById(id);// 在数据库中也查不到则返回一个错误信息或者返回空if (shop == null){return Result.fail("店铺不存在!!");}// 在数据库中查到了则把shop对象转为json字符串String jsonStr = JSONUtil.toJsonStr(shop);// 将转换后的json字符串存入RedisstringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY + id, jsonStr);// 最终把查询到的店铺信息返回给前端return Result.ok(shop);}
}

添加商户类型数据缓存

当我们访问首页时,会自动发起shop-type/list请求,查询不同商户类型的信息,由于这部分数据几乎是不变动的,所以我们可以将其一直存入Redis缓存

在这里插入图片描述

使用foreach循环将查询到的多个店铺类型信息从JSON和Bean之间相互转换,Redis中存储所有店铺类型的信息可以使用List类型

data:[0: {id: 1, name: "美食", icon: "/types/ms.png", sort: 1}
1: {id: 2, name: "KTV", icon: "/types/KTV.png", sort: 2}
2: {id: 3, name: "丽人·美发", icon: "/types/lrmf.png", sort: 3}
3: {id: 10, name: "美睫·美甲", icon: "/types/mjmj.png", sort: 4}
4: {id: 5, name: "按摩·足疗", icon: "/types/amzl.png", sort: 5}
5: {id: 6, name: "美容SPA", icon: "/types/spa.png", sort: 6}
6: {id: 7, name: "亲子游乐", icon: "/types/qzyl.png", sort: 7}
7: {id: 8, name: "酒吧", icon: "/types/jiuba.png", sort: 8}
8: {id: 9, name: "轰趴馆", icon: "/types/hpg.png", sort: 9}
9: {id: 4, name: "健身运动", icon: "/types/jsyd.png", sort: 10}]
// Redis中缓存所有店铺类型信息的List集合的key
public static final String CACHE_SHOP_TYPE_KEY = "cache:shop:type";
@GetMapping("list")
public Result queryTypeList() {return typeService.queryList();
}
public interface IShopTypeService extends IService<ShopType> {Result queryList();
}
@Override
public Result queryList() {// 先从Redis中查询缓存店铺类型信息的对应List集合中,这里的常量值Redis中缓存所有店铺类型信息的List集合的keyList<String> shopTypes = stringRedisTemplate.opsForList().range(CACHE_SHOP_TYPE_KEY, 0, -1);// 如果List集合不为空即查询到了店铺类型信息,则将List集合中每个String类型JSON字符串转为ShopType类型直接返回if (!shopTypes.isEmpty()) {List<ShopType> tmp = new ArrayList<>();for (String types : shopTypes) {ShopType shopType = JSONUtil.toBean(types, ShopType.class);tmp.add(shopType);}return Result.ok(tmp);}// 如果Redis中没有对应的List集合,则去数据库表中查询所有店铺类型的信息List<ShopType> tmp = query().orderByAsc("sort").list();if (tmp == null){return Result.fail("店铺类型不存在!!");}// 将查到的每个shopType类型的对象转换为JSON字符串,然后存入Redis中缓存店铺类型信息的List集合中for (ShopType shopType : tmp) {String jsonStr = JSONUtil.toJsonStr(shopType);shopTypes.add(jsonStr);}// 向Redis中存入查询到的List集合stringRedisTemplate.opsForList().leftPushAll(CACHE_SHOP_TYPE_KEY,shopTypes);// 最终把查询到的所有商户类型信息返回给前端return Result.ok(tmp);
}// 使用stream流简化代码
@Override
public Result queryList() {// 先从Redis中查询缓存店铺类型信息的对应List集合,这里的常量值Redis中缓存所有店铺类型信息的List集合的keyList<String> shopTypes = stringRedisTemplate.opsForList().range(CACHE_SHOP_TYPE_KEY, 0, -1);// 如果List集合不为空即查询到了店铺类型信息,则将List集合中每个String类型JSON字符串转为ShopType类型直接返回if (!shopTypes.isEmpty()) {List<ShopType> tmp = shopTypes.stream().map(type -> JSONUtil.toBean(type, ShopType.class)).collect(Collectors.toList());return Result.ok(tmp);}// 如果Redis中没有对应的List集合,则去数据库表中查询所有店铺类型的信息List<ShopType> tmp = query().orderByAsc("sort").list();if (tmp == null){return Result.fail("店铺类型不存在!!");}// 将查到的每个shopType类型的对象转换为JSON字符串,然后存入Redis中缓存店铺类型信息的List集合中shopTypes = tmp.stream().map(type -> JSONUtil.toJsonStr(type)).collect(Collectors.toList());// 向Redis中存入查询到的List集合stringRedisTemplate.opsForList().leftPushAll(CACHE_SHOP_TYPE_KEY,shopTypes);// 最终把查询到的所有商户类型信息返回给前端return Result.ok(tmp);
}

相关文章:

03黑马店评-添加商户缓存和商户类型的缓存到Redis

商户查询缓存 什么是缓存 实际开发过程中数据量可以达到几千万,缓存可以作为避震器防止过高的数据访问猛冲系统,避免系统内的操作线程无法及时处理信息而瘫痪 缓存(Cache)就是数据交换的缓冲区(储存临时数据的地方),我们俗称的"缓存"实际就是缓冲区内的数据(一般从…...

LabVIEW玩转魔方

LabVIEW玩转魔方 使用LabVIEW创建一个3D魔方&#xff0c;并找出解谜题的秘密&#xff0c;给朋友留下深刻深刻的印象。游戏中内置的机制使每张脸都能独立转动&#xff0c;从而混合颜色。要解决难题&#xff0c;每个面必须是相同的纯色 魔方的奥秘在于它的简单性和不可解性。这是…...

大数据学习(1)-Hadoop

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 承认自己的无知&#xff0c;乃是开启智慧的大门 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博>主哦&#x…...

常用时序模型

常用时序模型 RNN (Recurrent Neural Network): 基本概念: RNN是一种可以处理序列数据的神经网络。它在每一时间步都接收一个新的输入,并将前一个时间步的隐藏状态作为额外的输入。问题: 它的主要问题是在处理长序列时遇到的梯度消失和梯度爆炸。这使得RNN难以捕获长期依赖关…...

阿里云/腾讯云国际站:私服服务器:什么是游戏虚拟服务器及用途讲解?

游戏虚拟服务器是一种新兴的技术&#xff0c;它可以为玩家提供更好的游戏体验。私服服务器它可以将游戏服务器的负载分散到多台服务器上&#xff0c;从而提高游戏的流畅度和稳定性。此外&#xff0c;游戏虚拟服务器还可以提供更多的游戏功能&#xff0c;比如游戏聊天室、游戏排…...

ssti 前置学习

python venv环境 可以把它想象成一个容器&#xff0c;该容器供你用来存放你的Python脚本以及安装各种Python第三方模块&#xff0c;容器里的环境和本机是完全分开的 创建venv环境安装flask #apt install python3.10-venv #cd /opt #python3 -m venv flask1 #cd /opt 选…...

uni-app:服务器端数据绘制echarts图标(renderjs解决手机端无法显示问题)

效果 代码 <template><view click"echarts.onClick" :prop"option" :change:prop"echarts.updateEcharts" id"echarts" class"echarts"></view> </template><script>export default {data()…...

Python集合魔法:解锁数据去重技巧

更多资料获取 &#x1f4da; 个人网站&#xff1a;涛哥聊Python 在Python编程的魔法世界中&#xff0c;有一种数据类型几乎被忽视&#xff0c;但却拥有强大的超能力&#xff0c;那就是集合&#xff08;Set&#xff09;。 集合是一种无序、唯一的数据类型&#xff0c;它以其独…...

flutter开发实战-inappwebview实现flutter与Javascript的交互JSBridge

flutter开发实战-inappwebview实现flutter与Javascript的交互JSBridge 在使用webview中&#xff0c;需要实现flutter与Javascript交互&#xff0c;在使用webview_flutter插件的时候&#xff0c;整理了一下webview与Javascript的交互JSBridge&#xff0c;具体可以查看 https:/…...

私有云盘:lamp部署nextcloud+高可用集群

目录 一、实验准备&#xff1a; 二、配置mariadb主从复制 三台主机下载mariadb 1&#xff09;主的操作 2&#xff09;从的操作 3&#xff09;测试数据是否同步 三、配置nfs让web服务挂载 1、安装 2、配置nfs服务器 3、配置web服务的httpd 4、测试 四、web 服务器 配…...

在线制作课程表

失业在家&#xff0c;开启一天一个应用的创作节奏&#xff0c;最近学了uniapp&#xff0c;特别想做点啥&#xff0c;正好家里小孩子要打印课程表&#xff0c;而且课程表还有调课的需求&#xff0c;就寻思做一个方便大家&#xff0c;到目前位置服务完全免费的&#xff0c;新鲜上…...

聊聊分布式架构06——[NIO入门]简单的Netty NIO示例

目录 Java NIO和Netty NIO比较 Java NIO&#xff1a; Netty&#xff1a; Netty NIO中的主要模块 Transport&#xff08;传输层&#xff09; Buffer&#xff08;缓冲区&#xff09; Codec&#xff08;编解码器&#xff09; Handler&#xff08;处理器&#xff09; Even…...

H5逆向之远程RPC

引言前一讲说过H5 怎么去抓包,逆向分析。其中说到RPC。这一节详细讲一下。有一种情况,JS 比较复杂,混淆的厉害。 这个时候就用到RPC。原理就是,hook web 浏览器,直接调用js 里边的方法。 Node 服务。为什么用到Node 服务,先来看下这架构 Node 对外提供各种接口,外部可以…...

解决Ubuntu18.04安装好搜狗输入法后无法打出中文的问题

首先下载安装 搜狗拼音输入法 &#xff0c;下载选择&#xff1a; x86_64 在ubuntu中设置 fcitx 最后发现安装好了&#xff0c;图标有了 &#xff0c;但是使用时不能输入中文&#xff0c;使用下面的命令解决&#xff1a; sudo apt install libqt5qml5 libqt5quick5 libqt5qu…...

Ubuntu LabelMe AI 识别

1.创建虚拟环境 conda create -n labelme python3.9 2.激活虚拟环境 conda activate labelme 3.安装labelme pip install pyqt5 -i https://pypi.tuna.tsinghua.edu.cn/simple pip install pillow -i https://pypi.tuna.tsinghua.edu.cn/simple pip install labelme -i ht…...

基于FPGA的图像缩小算法实现,包括tb测试文件和MATLAB辅助验证

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 将FPGA的处理结果导出到matlab中显示图像效果&#xff1a; 2.算法运行软件版本 vivado2019.2 matlab2022a 3.部分核心程序 timescale 1ns / 1p…...

黑马店评-04缓存更新策略,保证MySQL数据库中的数据和Redis中缓存的数据一致性

缓存更新策略(数据一致) 更新策略 缓存更新是Redis为了节约内存而设计出来的机制,当我们向Redis插入太多数据时就会导致缓存中的数据过多,所以Redis会对部分数据进行更新即淘汰 低一致性需求(数据长久不发生变化): 使用内存淘汰机制,例如店铺类型信息的查询缓存,因为这部分…...

matlab相机标定实验

实验原理 1. 相机标定坐标系 相机的参数对目标的识别、定位精度有很大的影响&#xff0c;相机标定就是为了求出相机的内外参数。标定中有3个不同层次的坐标系&#xff1a;世界坐标系、相机坐标系和图像坐标系&#xff08;图像物理坐标系和图像像素坐标系&#xff09;。世界坐…...

【每日一题Day343】LC2731移动机器人 | 脑筋急转弯+数学

移动机器人【LC2731】 有一些机器人分布在一条无限长的数轴上&#xff0c;他们初始坐标用一个下标从 0 开始的整数数组 nums 表示。当你给机器人下达命令时&#xff0c;它们以每秒钟一单位的速度开始移动。 给你一个字符串 s &#xff0c;每个字符按顺序分别表示每个机器人移动…...

疯狂java 1.7垃圾回收机制

内存泄漏&#xff1a;如果一些分配出去的内存得不到及时回收&#xff0c;就会引起系统运行速度下降&#xff0c;甚至导致程序瘫痪 Java程序的内存分配和回收都是由JRE在后台自动进行的。JRE会负责回收哪些不再使用的内存&#xff0c;这种机制被称为垃圾回收&#xff08;Garbag…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

轻量级Docker管理工具Docker Switchboard

简介 什么是 Docker Switchboard &#xff1f; Docker Switchboard 是一个轻量级的 Web 应用程序&#xff0c;用于管理 Docker 容器。它提供了一个干净、用户友好的界面来启动、停止和监控主机上运行的容器&#xff0c;使其成为本地开发、家庭实验室或小型服务器设置的理想选择…...

OpenGL-什么是软OpenGL/软渲染/软光栅?

‌软OpenGL&#xff08;Software OpenGL&#xff09;‌或者软渲染指完全通过CPU模拟实现的OpenGL渲染方式&#xff08;包括几何处理、光栅化、着色等&#xff09;&#xff0c;不依赖GPU硬件加速。这种模式通常性能较低&#xff0c;但兼容性极强&#xff0c;常用于不支持硬件加速…...

2025 后端自学UNIAPP【项目实战:旅游项目】7、景点详情页面【完结】

1、获取景点详情的请求【my_api.js】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http(/login/getWXSessionKey, {code,avatar}); };//…...

OpenHarmony标准系统-HDF框架之I2C驱动开发

文章目录 引言I2C基础知识概念和特性协议&#xff0c;四种信号组合 I2C调试手段硬件软件 HDF框架下的I2C设备驱动案例描述驱动Dispatch驱动读写 总结 引言 I2C基础知识 概念和特性 集成电路总线&#xff0c;由串网12C(1C、12C、Inter-Integrated Circuit BUS)行数据线SDA和串…...