Springboot+Redis:实现缓存 减少对数据库的压力

🎉🎉欢迎光临,终于等到你啦🎉🎉

🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀

🌟持续更新的专栏Redis实战与进阶

本专栏讲解Redis从原理到实践

这是苏泽的个人主页可以看到我其他的内容哦👇👇

努力的苏泽icon-default.png?t=N7T8http://suzee.blog.csdn.net/


缓存如何实现?面试必考题  请看 我的讲解以及最佳实践吧

目录

缓存如何实现?面试必考题  请看 我的讲解以及最佳实践吧

关于 Redis 缓存的解释如下:

实现思路图

商户缓存跟着视频做的,然后我按照同样的方法逻辑 把商店类型的缓存自己做了一遍

首先注册一个IShopTypeService服务的对象typeService 然后直接调用typeService的方法queryTypeList()

下一节我们来讲解 Redis缓存击穿 缓存雪崩等缓存更新会发生的问题  都是Redis的面试必考题


关于 Redis 缓存的解释如下:

  1. Redis 如何实现缓存?
    在后端接收到请求后,对于需要进行缓存的接口,首先会在 Redis 中查找是否有对应的数据。如果缓存中不存在数据,系统会继续按照正常的业务流程处理请求,并将查询到的结果返回给客户端的同时也存储在 Redis 中。下次相同的请求到达时,系统可以直接从 Redis 中获取数据,而无需访问数据库。

在启用缓存后,相同的请求在缓存有效期内不会再去读取数据库。但是,如果在此期间修改了数据库中的数据,接口返回的数据就无法保证与数据库一致。因此,在进行增、删、改操作时,需要刷新缓存。

  1. Redis 缓存更新策略是什么?
    缓存更新可以采用不同的策略,以下是两种常见情况的比较:

第一种情况是先更新数据库,然后同步更新缓存,或者先更新缓存,然后同步更新数据库。这两种方式都属于写穿透(write through)策略。同步更新的好处是可以保持数据的一致性,但缺点是同步更新会对性能产生影响。

第二种情况是先更新缓存,然后异步写回数据库,也被称为写回(write back)策略。异步写回的优点是不会影响缓存的高性能,能够快速响应客户端请求。但缺点是在数据异步写回数据库之前,缓存与数据库的数据可能短暂不一致。

实现思路图

商户缓存跟着视频做的,然后我按照同样的方法逻辑 把商店类型的缓存自己做了一遍

以下是步骤

首先注册一个IShopTypeService服务的对象typeService 然后直接调用typeService的方法queryTypeList()

@RestController
@RequestMapping("/shop-type")
public class ShopTypeController {
    @Resource
    private IShopTypeService typeService;

    @GetMapping("list")
    public Result queryTypeList() {
//        List<ShopType> typeList = typeService.query().orderByAsc("sort").list();
        return typeService.queryTypeList();
    }
}

在IShopTypeService接口中我们定义这个抽象方法 然后在IShopTypeService的实现类IShopTypeServiceImp中实现这个方法

public interface IShopTypeService extends IService<ShopType> {

    Result queryTypeList();
}
@Service
public class ShopTypeServiceImpl extends ServiceImpl<ShopTypeMapper, ShopType> implements IShopTypeService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource//引入mybatis的接口 用于查数据库
    private IShopTypeService shopTypeService;
    @Override
    public Result queryTypeList() {
        //1.从redis中查询有无
        String shopTypeJson = stringRedisTemplate.opsForValue().get("shopType");
        //2.判断是否存在
        if (StrUtil.isNotBlank(shopTypeJson)){
            //3.存在直接返回 JSONUtil.parseArray将JSON 数组字符串转换为 Java 对象列表
            List<ShopType> shopType= BeanUtil.copyToList(JSONUtil.parseArray(shopTypeJson), ShopType.class);
//            System.err.println(shopType);
            return Result.ok(shopType);
        }
        //不存在 查询数据库
        List<ShopType> shopTypeList = shopTypeService.query().orderByAsc("sort").list();

        //数据库不存在 返回报错
        if (shopTypeList ==null) {
            return Result.fail("查询失败");
        }
        //数据库存在 写入redis  返回
        //将list转换成json 要用toJsonStr不能toString
        String str = JSONUtil.toJsonStr(shopTypeList);
        stringRedisTemplate.opsForValue().set("shopType",str);
//        System.err.println(str);
        return Result.ok(shopTypeList);
    }
}
  • 首先,从 Redis 中查询数据是否存在。
  • 如果数据存在,将 JSON 数组字符串转换为 List<ShopType> 对象,并直接返回结果。
  • 如果数据不存在于 Redis 中,则从数据库查询商店类型列表。
  • 如果数据库查询失败,返回查询失败的错误信息。
  • 如果数据库查询成功,将查询结果转换为 JSON 字符串,并存储到 Redis 中。
  • 最后,返回查询结果。

下一节我们来讲解 Redis缓存击穿 缓存雪崩等缓存更新会发生的问题  都是Redis的面试必考题

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

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

相关文章

fastjson反序列化攻略

漏洞原理 Json.parseObject(json, User.class)方法中&#xff0c;通过指定type的值实现定位某类&#xff0c;会执行User类的构造方法和属性中的get&#xff0c;set方法 判断是否是fastjson/&#xff08;jackson&#xff09; 1.2.24-1.2.83都会有dnslog的payload {"zer…

解决重装系统之后,开始菜单找不到Anaconda3相关图标

一、anaconda3安装后在开始菜单找不到&#xff0c;如下图所示 二、进入Anaconda3安装的位置 在安装位置按住shift键鼠标右键&#xff0c;打开poworshell&#xff0c;输入 start cmd最后的结果如图。

快速从0-1完成聊天室开发——环信ChatroomUIKit功能详解

聊天室是当下泛娱乐社交应用中最经典的玩法&#xff0c;通过调用环信的 IM SDK 接口&#xff0c;可以快速创建聊天室。如果想根据自己业务需求对聊天室应用的 UI界面、弹幕消息、礼物打赏系统等进行自定义设计&#xff0c;最高效的方式则是使用环信的 ChatroomUIKit 。 文档地址…

Java-SpringAop 编程式事物实现

SpringAop 编程式事物实现 1. 数据库事物特性 原子性 多个数据库操作是不可分割的&#xff0c;只有所有的操作都执行成功&#xff0c;事物才能被提交&#xff1b;只要有一个操作执行失败&#xff0c;那么所有的操作都要回滚&#xff0c;数据库状态必须回复到操作之前的状态 …

如何在三个简单步骤中为对象检测标注图像

初始通过彻底清洗和处理原始图像数据来奠定有效对象检测注释的基础。选择适合的工具、方法和清晰的注释过程指南来建立注释工作空间。通过在图像中划定对象并附上类别标签来执行注释&#xff0c;随后进行细致的核验&#xff0c;以确保数据集的精确性和完整性。 图像注释是计算…

C语言---指针的两个运算符:点和箭头

目录 点&#xff08;.&#xff09;运算符箭头&#xff08;->&#xff09;运算符需要注意实际例子 C语言中的指针是一种特殊的变量&#xff0c;它存储了一个内存地址。点&#xff08;.&#xff09;和箭头&#xff08;->&#xff09;是用于访问结构体和联合体成员的运算符。…

Java 多线程(抢CPU)

哈哈哈 什么是多线程&#xff1a;可以让程序同时做多件事情。 多线程的作用&#xff1a;提高效率。 多线程的应用场景&#xff1a;想让多个事情同时运行。 并发&#xff08;多个指令在单个CPU交替执行&#xff09;和并行&#xff08;多个指令在多个CPU交替执行&#xff09; …

面试算法-51-翻转二叉树

题目 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1] 解 class Solution {public TreeNode invertTree(TreeNode root) {dfs(root);re…

【C语言进阶篇】自定义类型:结构体(上)

目录 1. 结构体类型的声明 ​编辑 1.1 结构体的创建和初始化 1.2 结构体的特殊声明 1.3 结构体的自引用 2. 结构体内存对齐 2.1 对齐规则 2.2 为什么存在内存对齐 2.3 修改默认对齐数 在我们描述简单对象的时候&#xff0c;使用已有的类型就足够了&#xff0c;比如: 但是当我们…

堆排序(数据结构)

本期讲解堆排序的实现 —————————————————————— 1. 堆排序 堆排序即利用堆的思想来进行排序&#xff0c;总共分为两个步骤&#xff1a; 1. 建堆 • 升序&#xff1a;建大堆 • 降序&#xff1a;建小堆 2. 利用堆删除思想来进行排序. 建堆和堆删…

代码随想录|Day21|回溯01|77.组合

77.组合 组合问题不考虑顺序&#xff0c;例如 [1, 2] 和 [2, 1] 是同一个组合。其中 n 为取数的范围&#xff0c;每个组合包含 k个 元素数量&#xff0c;所以我们嵌套 k 个 for循环 可以很容易写出暴力解法。但如果 k 的值过大&#xff0c;代码将会非常冗长。 我们考虑回溯&…

基于”Python+”多技术融合在蒸散发与植被总初级生产力估算中的应用教程

原文链接&#xff1a;基于”Python”多技术融合在蒸散发与植被总初级生产力估算中的应用教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247598050&idx5&sn70fd3f5946d581ad9c1363295b130ef5&chksmfa823e05cdf5b713baf9cf1381bfb2455ad675a0b21e194…

Unity类银河恶魔城学习记录11-2 p104 Inventoty源代码

此章节相对较难理解&#xff0c;有时间单独出一章讲一下 Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili InventoryItem.cs…

C++ Qt开发:QUdpSocket网络通信组件

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍如何运用QUdpSocket组件实现基于UDP的网络通信…

Java安全 反序列化(1) URLDNS链原理分析

Java安全 反序列化(1) URLDNS链原理分析 文章目录 Java安全 反序列化(1) URLDNS链原理分析前置知识应用分析payload1.新建HashMap类2.新建URL类3.获取URL 的 Class对象4.通过反射访问URL内部变量5.通过反射为URL中类赋值6.调用HashMap#put方法传入key和value7.再次通过反射为UR…

基于51单片机PT100温度检测LCD1602显示(程序+原理图+PCB+仿真+全套资料)

功能介绍&#xff1a;采用51单片机和MAX13865模块PT100传感器LCD1602显示屏&#xff0c;通过PT100传感器感知稳定&#xff0c;MAX13865模块进行转换&#xff0c;采用SPI协议和单片机进行通信&#xff0c;将温度传送到单片机&#xff0c;然后单片机将数据显示到LCD1602屏幕上。 …

ModbusTCP转Profinet网关高低字节交换切换

背景&#xff1a;在现场设备与设备通迅之间通常涉及到从一种字节序&#xff08;大端或小端&#xff09;转换到另一种字节序。大端字节序是指高位字节存储在高地址处&#xff0c;而小端字节序是指低位字节存储在低地址处。在不动原有程序而又不想或不能添加程序下可选用ModbusTC…

深入探讨Python中的文件操作与文件IO操作【第141篇—Python实现】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 深入探讨Python中的文件操作与文件IO操作 在Python编程中&#xff0c;文件操作和文件IO操作…

【Swing】Java Swing实现省市区选择编辑器

【Swing】Java Swing实现省市区选择编辑器 1.需求描述2.需求实现3.效果展示 系统&#xff1a;Win10 JDK&#xff1a;1.8.0_351 IDEA&#xff1a;2022.3.3 1.需求描述 在公司的一个 Swing 的项目上需要实现一个选择省市区的编辑器&#xff0c;这还是第一次做这种编辑器&#xf…

第四百一十一回

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"给geolocator插件提交问题的结果"相关的内容&#xff0c;本章回中将介绍自定义标题栏.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我…
最新文章