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);
}

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

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

相关文章

Docker与Serverless计算的集成: Docker容器如何与Serverless计算结合。

文章目录 1. Docker容器的可移植性2. Serverless计算的自动伸缩性3. 使用Serverless与Docker容器a. 自托管Serverless平台b. 使用容器服务 4. 使用案例&#xff1a;图像处理服务5. 结论 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &#x1f389;…

【常用页面记录】vue+elementUI实现搜索框+上拉加载列表

一、代码 <template><div class"mainBox"><div class"headbox"><el-input placeholder"请输入文件名称搜索" prefix-icon"el-icon-search" v-model"fileName" :clearable"true" change&qu…

【Linux服务端搭建及使用】

连接服务器的软件&#xff1a;mobaxterm 设置root 账号 sudo apt-get install passwd #安装passwd 设置方法 sudo passwd #设置root密码 su root #切换到root账户设置共享文件夹 一、强制删除原有环境 1.删除python rpm -qa|grep pytho…

获取西华大学新闻网站信息(爬虫样例)

利用python的爬虫功能进行信息爬取&#xff0c;关键在于源码分析&#xff0c;代码相对简单。 1 源代码分析 访问网站&#xff0c;按下F12&#xff0c;进行元素查找分析。 2 代码实现 from requests import get from bs4 import BeautifulSoupdef getXhuNews(pageNum1):&qu…

【每日一记】OSPF区域划分详讲、划分区域的优点好处

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大二在校生&#xff0c;喜欢编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;小新爱学习. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc…

家政服务行业做开发微信小程序可以实现什么功能

家政服务行业开发微信小程序可以实现多种功能&#xff0c;从而提升服务品质和效率&#xff0c;下面我们来详细介绍一些可能实现的功能。 一、展示服务信息 家政服务微信小程序可以展示各种服务信息&#xff0c;包括各类家政服务项目、价格、服务流程、服务人员信息等。用户可以…

岛屿的数量

题目描述 给你一个由 ‘1’&#xff08;陆地&#xff09;和 ‘0’&#xff08;水&#xff09;组成的的二维网格&#xff0c;请你计算网格中岛屿的数量。 岛屿总是被水包围&#xff0c;并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此外&#xff0c;你可以…

通过后台系统添加一段div,在div中写一个<style></style>标签来修改div外面的元素的深层元素的样式

先看图 btn元素就是通过后台系统加上的元素,现在需要通过在btn里面写一个style标签来修改grid-nine里面的head元素的高度.开始想通过style来修改,但是不知道怎么去获取这个div外面的元素,想通过js方法去修改,写了script标签加了js代码,但不生效,后面问了才知道,这个项目是vue打…

MES系统安灯管理:实时可视化生产线状态

一、MES系统安灯管理的意义&#xff1a; 安灯管理是指通过使用不同颜色的灯光信号来表示生产线的状态&#xff0c;以便生产人员能够直观地了解生产线的运行情况。MES系统安灯管理的意义在于提供一个实时可视化的工具&#xff0c;使制造企业能够及时发现生产线异常和潜在问题&a…

light client轻节点简介

1. 引言 前序博客&#xff1a; Helios——a16z crypto构建的去中心化以太坊轻节点 去中心化和自我主权对于Web3的未来至关重要&#xff0c;但是这些理想并不总适用于每个项目或应用程序。在非托管钱包和bridges等工具中严格优先考虑安全性而不是便利性的用户&#xff0c;可选…

设计模式 - 结构型模式考点篇:适配器模式(类适配器、对象适配器、接口适配器)

目录 一、适配器模式 一句话概括结构式模式 1.1、适配器模式概述 1.2、案例 1.2.1、类适配器模式实现案例 1.2.2、对象适配器 1.2.3、接口适配器 1.3、优缺点&#xff08;对象适配器模式&#xff09; 1.4、应用场景 一、适配器模式 一句话概括结构式模式 教你将类和对…

阿里云上了新闻联播

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 阿里新任的CEO吴泳铭上央视新闻联播了! 在昨天的新闻联播里&#xff0c;出席科技座谈会&#xff0c;有一个特别镜头&#xff0c;出现了阿里新任CEO吴泳铭的镜头。 这个信号意义明显&#xff0c;我…

kali linux安装redis

官网&#xff1a;Install Redis from Source | Redis wget https://download.redis.io/redis-stable.tar.gztar -xzvf redis-stable.tar.gz cd redis-stable make显示如下即可进入下一步 sudo make installredis-server 可以看到已经可以使用了。 但是由于第一次使用导致了re…

Rust专属开发工具——RustRover发布

JetBrains最近推出的Rust集成开发工具——RustRover已经发布&#xff0c;官方网站&#xff1a;RustRover: Rust IDE by JetBrains JetBrains出品过很受欢迎的开发工具IntelliJ IDEA、PyCharm等。 RustRover优势 Rust集成环境&#xff0c;根据向导可自动下载安装rust开发环境提…

Centos7中安装Jenkins教程

1.必须先配置jdk环境&#xff0c;安装jdk参考 Linux配置jdk 2.先卸载Jenkins # rpm卸载 rpm -e jenkins # 检查是否卸载成功 rpm -ql jenkins # 彻底删除残留文件 find / -iname jenkins | xargs -n 1000 rm -rf 3.安装Jenkins 在 /usr/ 目录下创建 jenkins文件夹 mkdir -p je…

Maven 构建Java项目

Maven 使用原型 archetype 插件创建项目。要创建一个简单的 Java 应用&#xff0c;我们将使用 maven-archetype-quickstart 插件。 在下面的例子中&#xff0c;我们将在 C:\MVN 文件夹下创建一个基于 maven 的 java 应用项目。 命令格式如下&#xff1a; mvn archetype:gene…

微信小程序--》从模块小程序项目案例23.10.09

配置导航栏 导航栏是小程序的门户&#xff0c;用户进来第一眼看到的便是导航栏&#xff0c;其起着对当前小程序主题的概括。而我们 新建的小程序 时&#xff0c;第一步变开始配置导航栏。如下&#xff1a; 配置tabBar 因为配置tabBar需要借助字体图标&#xff0c;我这里平常喜…

【数据库——MySQL】(16)游标和触发器习题及讲解

目录 1. 题目1.1 游标1.2 触发器 2. 解答2.1 游标2.2 触发器 1. 题目 1.1 游标 创建存储过程&#xff0c;利用游标依次显示某部门的所有员工的实际收入。(分别用使用 计数器 来循环和使用 标志变量 来控制循环两种方法实现) 创建存储过程&#xff0c;将某部门的员工工资按工作…

前端js调试如何复制console.log打印的对象或数组

在使用console.log()打印我们的内容时&#xff0c;时常需要将打印的内容复制粘贴使用&#xff0c;然而控制台打印出来的对象是经过格式化处理且直接选择粘贴会有格式问题&#xff0c;此时我们可以通过控制台的 copy() 方法来进行打印结果的复制&#xff0c;如图所示&#xff1a…