基于Redis提高查询性能(保持数据一致性)

Redis实战篇 | Kyle's Blog (cyborg2077.github.io)

目录

背景

商户查询缓存(根据ID查询)

 根据店铺类型查询(List型)

缓存更新策略(保证数据一致性)

案例(利用缓存更新策略)


背景

起初客户端直接向数据库查询数据                              添加redis后 

商户查询缓存(根据ID查询)

 实现业务流程

 ShopController

    @GetMapping("/{id}")public Result queryShopById(@PathVariable("id") Long id) {return shopService.queryById(id);}

IShopService 

public interface IShopService extends IService<Shop> {Result queryById(Long id);
}

ShopServiceImpl 

@Service
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {@Resourcepublic StringRedisTemplate stringRedisTemplate;@Overridepublic Result queryById(Long id) {String key = CACHE_SHOP_KEY + id;// 1.从redis查询商铺缓存String shopJson = stringRedisTemplate.opsForValue().get(key);// 2.判断缓存是否命中if(StrUtil.isNotBlank(shopJson)){// 3.缓存命中,返回// 将json反序列化为对象Shop shop = JSONUtil.toBean(shopJson, Shop.class);return Result.ok(shop);}// 4.缓存未命中,根据id查询数据库Shop shop = getById(id);// 5.数据库不存在,返回错误if(shop == null){return Result.fail("店铺不存在");}// 6.数据库存在,写入缓存stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop),30L, TimeUnit.MINUTES);// 7.返回return Result.ok(shop);}
}

 根据店铺类型查询(List型)

Controller 

@RestController
@RequestMapping("/shop-type")
public class ShopTypeController {@Resourceprivate IShopTypeService typeService;@GetMapping("list")public Result queryTypeList() {return typeService.queryList();}
}

接口 

public interface IShopTypeService extends IService<ShopType> {Result queryList();
}

实现类

@Service
public class ShopTypeServiceImpl extends ServiceImpl<ShopTypeMapper, ShopType> implements IShopTypeService {@Resourcepublic StringRedisTemplate stringRedisTemplate;@Overridepublic Result queryList() {// 1.从redis查询商铺类型List<String> shopTypes = stringRedisTemplate.opsForList().range(CACHE_SHOP_KEY, 0, -1);// 2.判断redis是否命中if(!shopTypes.isEmpty()){//如果命中则转为ShopType类型返回List<ShopType> tmp = new ArrayList<>();for (String types : shopTypes) {ShopType shopType = JSONUtil.toBean(types, ShopType.class);tmp.add(shopType);}return Result.ok(tmp);}//没有命中则查询数据库List<ShopType> tmp = query().orderByAsc("sort").list();if(tmp.isEmpty()){return Result.fail("店铺类型不存在");}//3.将数据写入redisshopTypes.forEach(shopType -> {stringRedisTemplate.opsForList().rightPush(CACHE_SHOP_KEY,JSONUtil.toJsonStr(shopType));});//4.返回return Result.ok(tmp);}
}

缓存更新策略(保证数据一致性)

 三种更新缓存的策略(保证数据一致性)

我们主要使用主动更新策略

又因为操作数据库和缓存的先后顺序,线程问题;因此需要先修改数据库,再删除缓存,加锁,使用事务。

案例(利用缓存更新策略)

根据id查询店铺时,如果缓存未命中,则查询数据库,将数据库结果写入缓存,并设置超时时间 

// 6.数据库存在,写入缓存
stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop), CACHE_SHOP_TTL , TimeUnit.MINUTES);

根据id修改店铺时,先修改数据库,再删除缓存

    @Override@Transactionalpublic Result update(Shop shop) {Long id = shop.getId();if(id == null){return Result.fail("店铺id不能为空");}// 1.更新数据库updateById(shop);// 2.删除缓存stringRedisTemplate.delete(CACHE_SHOP_KEY + id);return Result.ok();}

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

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

相关文章

【pytorch01】简单回归问题

1.梯度下降&#xff08;Gradient Descent&#xff09; y x 2 ∗ s i n ( x ) yx^{2}*sin(x) yx2∗sin(x) y ′ 2 ∗ x ∗ s i n ( x ) x 2 ∗ c o s ( x ) y2*x*sin(x) x^{2}*cos(x) y′2∗x∗sin(x)x2∗cos(x) 求最小值要求导 梯度下降定义&#xff1a;梯度下降要迭代计…

互联网广告相关概念

互联网广告概念涉及多个关键指标和定价模式&#xff0c;它们帮助广告主和广告平台衡量广告效果、优化广告投放策略&#xff0c;并计算广告成本。以下是互联网广告中一些核心概念的简要概述&#xff1a; 1.ROI (投资回报率) 衡量广告投资的效益&#xff0c;计算公式为&#xff…

【决战欧洲杯巅峰】AI模型预测[走地数据]初步准备工作

数据准备 首先&#xff0c;我们需要收集一些与欧洲杯比赛相关的历史数据。这些数据可能包括球队的历史战绩、球员的能力评分、比赛场地信息、历史交锋记录等。这些数据可以从公开来源获取&#xff0c;并进行适当的预处理和清洗。 特征提取 接下来&#xff0c;我们需要从收集…

vue3+ts+vite集成eslint

项目中安装eslint yarn add eslint -Deslint初始化 npx eslint --init按照下方操作即可 安装typescript-eslint/parser yarn add typescript-eslint/parser -D安装vite-plugin-eslint2 yarn add vite-plugin-eslint2 -D配置vite-plugin-eslint2 // vite.config.ts import …

Flask新手入门(一)

前言 Flask是一个用Python编写的轻量级Web应用框架。它最初由Armin Ronacher作为Werkzeug的一个子项目在2010年开发出来。Werkzeug是一个综合工具包&#xff0c;提供了各种用于Web应用开发的工具和函数。自发布以来&#xff0c;Flask因其简洁和灵活性而迅速受到开发者的欢迎。…

【计算机网络仿真实验-实验2.7】单臂路由

实验2.7 单臂路由 1. 实验拓扑图 2. 测试连通性 测试PC1 PC2 PC3 之间的连通性 无法ping通&#xff0c;因为它们处在不同的网段&#xff0c;而二层交换机不具备路由功能&#xff0c;因此没办法接通 3. 在交换机上创建vlan10&#xff0c;并将端口0/2划分到vlan10中 Switch>…

Java并发编程深度解析:构建高并发应用的实践与探究

摘要&#xff1a;随着互联网技术的飞速发展&#xff0c;大型分布式系统对并发处理能力的要求越来越高。Java作为企业级应用的主流开发语言&#xff0c;在并发编程方面有着深厚的积累和强大的生态支持。本文将深入探讨Java并发编程的基础知识&#xff0c;高级技巧&#xff0c;以…

JavaScript 函数与事件

1. JavaScript自定义函数 语法&#xff1a; function 函数名&#xff08;参数列表&#xff09;{ 方法体; } 在函数被调用时&#xff0c;一个 arguments 对象就会被创建&#xff0c;它只能使用在函数体中&#xff0c;以数组的形式来管理函数的实际…

HTML基本标签使用【超链接标签、表格标签、表单标签、input标签】

目录 一、基本介绍1.1 概念1.2 HTML的核心特点 二、HTML基本标签三、超链接标签四、表格标签✌<table> 标签属性✍<tr> 标签属性✌ <td> 和 <th> 标签属性演示注意事项 五、表单标签综合应用 最后 一、基本介绍 1.1 概念 HTML&#xff0c;全称为超文…

小阿轩yx-Nginx Rewrite

小阿轩yx-Nginx Rewrite Nginx Rewrite 概述 现在 Nginx 已经成为很多公司作为前端反向代理服务器的首选 实际工作中会遇到很多跳转(重写 URL)的需求 更换域名后需要保持旧的域名能跳转到新的域名上某网页发生改变需要跳转到新的页面网站防盗链等等需求 后端使用的Nginx 服…

SpringBoot集成slf4j日志配置

目录 前言 1、slf4j概述 2、pom.xml的日志依赖 3、application.yml的日志配置 4、logback.xml配置文件定义 5、logback.xml配置文件解析 5.1 定义日志的存储路径 5.2 定义日志的输出格式 5.3 定义控制台输出 5.4 定义日志相关参数 5.5 定义日志的输出级别 6、测试日…

利用JAVA语言调用GLM-4接口实战指南

一、什么是API接口 API&#xff08;Application Programming Interface&#xff0c;应用程序编程接口&#xff09;是一种软件接口&#xff0c;它定义了不同应用程序之间如何相互通信、交互。API接口分为很多种&#xff0c;常见的有Web API&#xff0c;数据库API&#xff0c;操…

Perl语言快速入门学习

1. 引言 Perl&#xff08;Practical Extraction and Report Language&#xff09;是一种功能强大且灵活的编程语言&#xff0c;广泛应用于文本处理、系统管理、网络编程等领域。本文将带领大家了解Perl语言的基础知识&#xff0c;帮助初学者快速入门。 2. 什么是Perl&#xf…

数据结构-算法和算法分析

目录 前言一、算法1.1 算法与程序1.2 算法描述方法1.3 算法特性1.4 算法设计的要求 二、算法分析2.1 算法时间效率的度量2.1.1 事前分析方法算法的渐进时间复杂度算法时间复杂度分析例子算法最坏时间复杂度时间复杂度的计算规则 2.2 算法空间效率的度量 总结 前言 程序 数据结…

如何相互转换图片格式?如何转换jpg、bmp、png格式?

图片的格式有很多种&#xff0c;常见的有jpg、bmp、png格式&#xff0c;这些格式本质上没有太大区别&#xff0c;安卓和电脑都可以直接打开查看&#xff0c;但有时还是会用到一些固定的格式&#xff0c;例如&#xff0c;上传个人信息时&#xff0c;如果图片格式不符合要求&…

参数量Params和每秒浮点运算次数FLOPs的单位是多少

先看一下yolov8的表 模型计算量(FLOPs)和参数量(Params)是衡量深度学习算法复杂度的两个重要指标&#xff0c;它们可以用来评估一个模型的性能和实用性。以下是对这两个指标的理解&#xff1a; 1、Params - 参数量 即模型中需要学习的参数数量&#xff0c;它是衡量模型复杂度的…

pytorch基础【4】梯度计算、链式法则、梯度清零

文章目录 梯度计算计算图&#xff08;Computational Graph&#xff09;梯度求导&#xff08;Gradient Computation&#xff09;函数与概念 示例代码更多细节梯度求导的过程梯度求导的基本步骤示例代码注意事项总结 链式法则是什么&#xff1f;链式法则的数学定义链式法则在深度…

VMR,支持30+种编程语言的SDK版本管理器,支持Windows/MacOS/Linux。

官方文档地址&#xff1a;documents 官方项目地址&#xff1a;github 欢迎安装使用&#xff0c;分享转发&#xff0c;前往github star。 跨平台&#xff0c;支持Windows&#xff0c;Linux&#xff0c;MacOS支持多种语言和工具&#xff0c;省心受到lazygit的启发&#xff0c;拥…

Flutter【组件】可折叠文本组件

简介 flutter 可折叠文本组件。 点击展开&#xff0c;收起折叠文本。支持样式自定义 github地址&#xff1a; github.com/ThinkerJack… pub地址&#xff1a;https://pub.dev/packages/jac_uikit 展开收起文本 使用方式&#xff1a; ExpandableText(content: 测试 * 50,ma…

qt基于QGraphicsView的屏幕旋转

一、代码实现 实现代码示例 MainWindow2 w;QGraphicsScene *scene new QGraphicsScene;QGraphicsProxyWidget *gw scene->addWidget(&w);// 旋转角度gw->setRotation(90);QGraphicsView *view new QGraphicsView(scene);//view->resize(1024, 600);//scene-&g…