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

Redis在项目开发中的应用

Spring Boot集成Redis构建博客应用

在这个示例中,我们将展示如何使用Spring Boot和Redis构建一个简单的博客应用,包括文章发布、点赞和评论功能。

1. 添加依赖

首先,我们需要在pom.xml文件中添加Spring Boot和Redis的依赖项。

<!-- Spring Boot -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><!-- Redis -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2. 配置Redis连接

application.propertiesapplication.yml文件中,我们需要配置Redis连接信息。

spring.redis.host=127.0.0.1
spring.redis.port=6379

3. 创建Redis操作的Repository

接下来,我们创建一个BlogRepository接口,用于定义与Redis交互的操作。

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;@Repository
public class BlogRepository {private final RedisTemplate<String, Blog> redisTemplate;private static final String KEY_PREFIX = "blog:";public BlogRepository(RedisTemplate<String, Blog> redisTemplate) {this.redisTemplate = redisTemplate;}public void save(Blog blog) {String key = KEY_PREFIX + blog.getId();redisTemplate.opsForValue().set(key, blog);}public Blog findById(String id) {String key = KEY_PREFIX + id;return redisTemplate.opsForValue().get(key);}public void delete(String id) {String key = KEY_PREFIX + id;redisTemplate.delete(key);}
}

4. 创建博客实体类

我们创建一个Blog实体类,用于表示博客的基本信息。

public class Blog {private String id;private String title;private String content;private int likes;private List<Comment> comments;// 省略构造函数、Getter和Setter方法
}

5. 编写业务逻辑

BlogService中,我们编写业务逻辑方法来发布博客、点赞和评论。

@Service
public class BlogService {private final BlogRepository blogRepository;public BlogService(BlogRepository blogRepository) {this.blogRepository = blogRepository;}public void publishBlog(Blog blog) {blogRepository.save(blog);}public void likeBlog(String blogId) {Blog blog = blogRepository.findById(blogId);blog.setLikes(blog.getLikes() + 1);blogRepository.save(blog);}public void addComment(String blogId, Comment comment) {Blog blog = blogRepository.findById(blogId);blog.getComments().add(comment);blogRepository.save(blog);}public void deleteBlog(String blogId) {blogRepository.delete(blogId);}
}

6. 创建控制器

最后,我们创建一个BlogController控制器类,处理HTTP请求。

@RestController
@RequestMapping("/blogs")
public class BlogController {private final BlogService blogService;public BlogController(BlogService blogService) {this.blogService = blogService;}@PostMappingpublic void publishBlog(@RequestBody Blog blog) {blogService.publishBlog(blog);}@PutMapping("/{blogId}/like")public void likeBlog(@PathVariable String blogId) {blogService.likeBlog(blogId);}@PutMapping("/{blogId}/comments")public void addComment(@PathVariable String blogId, @RequestBody Comment comment) {blogService.addComment(blogId, comment);}@DeleteMapping("/{blogId}")public void deleteBlog(@PathVariable String blogId) {blogService.deleteBlog(blogId);}
}

7. 运行应用

现在,您可以运行Spring Boot应用程序,并使用RESTful API来发布博客、点赞和评论。

总结:

通过上述示例,我们展示了如何在Spring Boot中集成Redis,并使用Redis存储和操作博客数据。通过BlogRepository类,我们可以将博客对象保存到Redis中,然后通过BlogService类对博客进行操作,最后通过BlogController类处理HTTP请求。

通过使用Redis作为数据存储,我们可以获得高性能和可扩展性。例如,我们可以使用Redis的计数器功能来实现点赞功能,并使用Redis的列表或有序集合来存储评论。

redis其他的应用

一、Redis高级案例:Set集合存储对象

在实际应用中,我们经常需要将某些对象或元素存储在集合结构中。Redis为我们提供了Set集合类型,可以高效地存储无序且不重复的元素。下面我们将创建一个用户信息Set集合,存储用户ID和用户名。

  1. 创建用户信息集合

首先,我们需要创建一个Redis服务器实例,并连接到该实例。在Spring Boot应用的配置文件中,我们可以配置Redis连接参数,例如主机名、端口、密码等。

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;public class RedisUtil {private final StringRedisTemplate stringRedisTemplate;public RedisUtil(String host, int port, String password) {this.stringRedisTemplate = new StringRedisTemplate();this.stringRedisTemplate.setHost(host);this.stringRedisTemplate.setPort(port);this.stringRedisTemplate.setPassword(password);}// 创建用户信息集合public void createUserInfoSet(String userId, String username) {RedisTemplate<String, String> redisTemplate = stringRedisTemplate.opsForSet();redisTemplate.add(userId, username);}
}
  1. 获取Set集合元素

现在我们来获取刚刚创建的用户信息Set集合中的元素。我们可以使用contains方法检查元素是否存在,也可以使用size方法获取集合大小。

public void checkUserInfo(String userId) {RedisTemplate<String, String> redisTemplate = stringRedisTemplate.opsForSet();boolean isExist = redisTemplate.contains(userId);System.out.println("User " + userId + " exists in the user info set.");if (!isExist) {System.out.println("User " + userId + " does not exist in the user info set.");}long size = redisTemplate.size("user-info");System.out.println("Size of the user info set: " + size);
}

二、Redis高级案例:分布式锁解决数据并发问题

在分布式系统中,数据并发问题是一个常见的挑战。为了确保数据的一致性和完整性,我们可以使用分布式锁来协调不同节点之间的操作。下面我们将展示如何使用Spring Boot和Redis实现一个简单的分布式锁示例。

  1. 定义分布式锁

在Spring Boot中,我们可以使用@Lock注解来定义分布式锁。这个注解允许我们在方法上添加一个lock()方法,用于获取锁,并在一定时间内阻塞其他线程。

@RestController
@RequestMapping("/example")
public class ExampleController {private final RedisLock redisLock;@Autowiredpublic ExampleController(RedisLock redisLock) {this.redisLock = redisLock;}// 定义获取锁的方法@Lockpublic void doSomething() {// 执行一些操作}
}
  1. 实现分布式锁的实现

为了实现分布式锁,我们需要使用Redis的SETNX命令。这个命令可以将一个键设置为一个唯一的值,如果这个键在Redis中不存在。我们可以在获取锁之前使用这个命令来设置一个锁键,如果锁键已经存在,则不设置,否则设置锁键并返回1。

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;@Service
public class DistributedLockService {private final RedisTemplate<String, byte[]> redisTemplate;@Autowiredpublic DistributedLockService(RedisTemplate<String, byte[]> redisTemplate) {this.redisTemplate = redisTemplate;}// 实现获取分布式锁的方法public boolean getDistributedLock(String lockKey) {byte[] value = redisTemplate.opsForValue().get(lockKey);if (value == null) {// 如果锁键不存在,则设置锁键并返回trueredisTemplate.opsForValue().set(lockKey, "1");return true;} else {// 如果锁键已经存在,则返回falsereturn false;}}
}
  1. 测试分布式锁

现在我们来测试一下分布式锁的效果。假设我们有两个线程同时调用doSomething()方法,一个线程先获取到锁,另一个线程后获取到锁。

public void testDistributedLock() {for (int i = 0; i < 10; i++) {Thread thread1 = new Thread(() -> {DistributedLockService distributedLockService = new DistributedLockService(applicationContext.getBean("redisTemplate"));boolean isLocked = distributedLockService.getDistributedLock("example-lock");if (isLocked) {System.out.println("Thread " + Thread.currentThread().getName() + " is locked.");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}} else {System.out.println("Thread " + Thread.currentThread().getName() + " cannot lock.");}});Thread thread2 = new Thread(() -> {DistributedLockService distributedLockService = new DistributedLockService(applicationContext.getBean("redisTemplate"));boolean isLocked = distributedLockService.getDistributedLock("example-lock");if (isLocked) {System.out.println("Thread " + Thread.currentThread().getName() + " is locked.");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}} else {System.out.println("Thread " + Thread.currentThread().getName() + " cannot lock.");}});

Redis是一个高性能的键值对存储系统,它可以用于各种场景,例如消息队列服务、缓存、排行榜等。在处理高并发、快速读写的场景时,Redis是一个非常好的选择。

当涉及到实际开发中的Redis使用案例时,除了常见的缓存和计数器之外,还有许多有趣且实用的用例。下面是一些更高级的Redis使用案例,以博客的形式进行讲解。

三. 消息队列实现

在现代应用程序中,消息队列是一种常见的用于异步通信和解耦的机制。在这篇博客中,我们将展示如何使用Redis的发布/订阅功能构建简单的消息队列系统。

首先,我们创建一个RedisMessagePublisher类,负责发布消息到Redis消息队列:

public class RedisMessagePublisher {private RedisTemplate<String, String> redisTemplate;private String channel;public RedisMessagePublisher(RedisTemplate<String, String> redisTemplate, String channel) {this.redisTemplate = redisTemplate;this.channel = channel;}public void publishMessage(String message) {redisTemplate.convertAndSend(channel, message);}
}

接下来,我们创建一个RedisMessageSubscriber类,用于订阅并处理接收到的消息:

public class RedisMessageSubscriber extends MessageListenerAdapter {@Overridepublic void onMessage(Message message, byte[] pattern) {String channel = new String(message.getChannel());String messageBody = new String(message.getBody());// 处理接收到的消息// ...}
}

最后,我们在Spring Boot应用程序中配置并使用消息队列。例如:

@Configuration
public class RedisMessageConfig {private RedisTemplate<String, String> redisTemplate;@Autowiredpublic RedisMessageConfig(RedisTemplate<String, String> redisTemplate) {this.redisTemplate = redisTemplate;}@Beanpublic MessageListenerAdapter messageListenerAdapter() {return new RedisMessageSubscriber();}@Beanpublic ChannelTopic channelTopic() {return new ChannelTopic("myChannel");}@Beanpublic RedisMessagePublisher redisMessagePublisher() {return new RedisMessagePublisher(redisTemplate, "myChannel");}
}

通过上述配置,我们可以在应用程序中使用RedisMessagePublisher来发布消息,而RedisMessageSubscriber会自动接收并处理这些消息。

总结

Redis在项目开发中有广泛的应用,总结起来主要体现在以下几个方面:

  1. 缓存:Redis是一种高速内存数据库,能够提供非常快速的读写速度。在项目开发中,我们可以使用Redis来缓存一些静态资源或者频繁访问的数据,从而提高系统的响应速度和用户体验。例如,我们可以将用户信息、商品信息等数据存储在Redis中,当用户访问网站时,直接从Redis中获取数据,避免了频繁地访问数据库。

  2. 消息队列:Redis支持发布/订阅模式,可以用作消息队列来处理系统内部的异步消息。例如,在电商项目中,我们可以使用Redis来缓存用户的购物车信息,然后在用户提交订单时,将订单信息发布到消息队列中,让其他服务异步处理订单。

  3. 分布式锁:Redis支持SETNX命令,该命令只有在指定的key不存在时才会设置key的值,这就可以用来实现分布式锁。例如,在微服务架构中,我们可以使用Redis来实现分布式锁来保证服务的原子性。

  4. 数据持久化:虽然Redis是一种内存数据库,但它支持数据持久化,可以将数据持久化到磁盘上。在项目开发中,我们可以使用Redis的持久化功能来实现数据的备份和恢复。

在应用Redis时,我们需要注意以下几点:

  1. Redis是基于内存的数据库,虽然提供了持久化功能,但数据的安全性仍然需要依赖于服务器的稳定性和磁盘的可靠性。因此,在设计系统时,我们需要考虑到这些因素。

  2. Redis的性能非常高,但如果数据量过大,可能会消耗大量的内存资源。因此,在使用Redis时,我们需要考虑到系统的内存容量。

  3. Redis的数据结构比较简单,虽然支持多种数据结构,但相比于其他数据库,它的功能相对较少。因此,在使用Redis时,我们需要根据实际需求选择合适的数据结构。

相关文章:

Redis在项目开发中的应用

Spring Boot集成Redis构建博客应用 在这个示例中&#xff0c;我们将展示如何使用Spring Boot和Redis构建一个简单的博客应用&#xff0c;包括文章发布、点赞和评论功能。 1. 添加依赖 首先&#xff0c;我们需要在pom.xml文件中添加Spring Boot和Redis的依赖项。 <!-- Sp…...

mapper向mapper.xml传参中文时的乱码问题

1.起因&#xff1a; 在idea中进行模糊查询传参时&#xff0c;发现在idea中查中文查不出记录&#xff0c;在navicate中可以查出来。 2.猜测&#xff1a; 1.idea中的编码问题导致的乱码。 2.idea和navicate的编码一致性导致的乱码。 3.mapper向mapper.xml传参后出现乱码。 3.解…...

基于Docker官方php:7.1.33-fpm镜像构建支持67个常见模组的php7.1.33镜像

实践说明&#xff1a;基于RHEL7(CentOS7.9)部署docker环境(23.0.1、24.0.2)&#xff0c;所构建的php7.1.33镜像应用于RHEL7-9(如AlmaLinux9.1)&#xff0c;但因为docker的特性&#xff0c;适用场景是不限于此的。 文档形成时期&#xff1a;2017-2023年 因系统或软件版本不同&am…...

Type-C PD充电器受电端sink诱骗取电汇总:小家电应用5V9V12V15V20V28V

小家电产品、美容产品、电动产品等升级采用Type-C接口&#xff0c;在Type-C接口上使用Type-C取电芯片&#xff0c;即可使用快速充电器的5V、9V、12V、15V、20V供电&#xff0c;无需再配充电器&#xff0c;各类品牌的充电器都可以支持。目前充电器常见的USB-PD功率为&#xff1a…...

禁用code server docker容器中的工作区信任提示

VSCode 添加受限模式&#xff0c;主要是防止自动运行代码的&#xff0c;比如在vscode配置的task和launch参数是可以运行自定义代码的。如果用VScode打开未知的工程文件就有可能直接运行恶意代码。 但是当我们的实验基础模板文件可控的情况下&#xff0c;要想禁用code server do…...

JSON格式插件-VUE

JsonEditor 安装&#xff1a; npm i bin-code-editor -S引入&#xff1a; import Vue from vue; import CodeEditor from bin-code-editor; import bin-code-editor/lib/style/index.css; import App from ./App.vue; Vue.use(CodeEditor); new Vue({el: #app,render: h > …...

dubbo的springboot集成

1.什么是dubbo&#xff1f; Apache Dubbo 是一款 RPC 服务开发框架&#xff0c;用于解决微服务架构下的服务治理与通信问题&#xff0c;官方提供了 Java、Golang 等多语言 SDK 实现。使用 Dubbo 开发的微服务原生具备相互之间的远程地址发现与通信能力&#xff0c; 利用 Dubbo …...

【人工智能】智能电网:未来能源的革命

未来能源的革命 智能电网革命的意义在于将电力行业从传统的集中式发电和集中式输配电模式转变为智能化、分布式、互动式的能源网络。 现在我们从以下方面详细认真的了解一下智能电网&#xff1a; 智能变电站&#xff0c;智能配电网&#xff0c;智能电能表&#xff0c;智能交互…...

【AIGC】一组精美动物AI智能画法秘诀

如何使用AI绘画&#xff0c;从以下角度&#xff0c;依据表格内容梳理&#xff0c;表格如下&#xff1a; 外貌特征物种姿势特征描述场景风格技术描述小巧可爱幼小浣熊倚在桌子上具有人形特征中世纪酒馆电影风格照明8k分辨率细节精致毛茸茸手持咖啡杯Jean-Baptiste Monge的风格蓝…...

JS 高频面试题

JS 的数据类型有哪些&#xff0c;有什么区别 基本数据类型&#xff08;Undefined、Null、Boolean、Number、String、Symbol&#xff09; 引用数据类型&#xff08;对象、数组和函数&#xff09; 区别&#xff1a; 原始数据类型直接存储在栈&#xff08;stack&#xff09;中的简…...

linux—多服务免密登录

文档结构 概念简介配置操作 概念简介 配置操作 场景&#xff1a;在部署gp集群时&#xff0c;希望 master 节点可以使用gpadmin用户可以实现免密登录 slave1和 slave2 节点&#xff1b; step_1: IP映射 xx.xx.xx.101 server-slave1 xx.xx.xx.102 server-slave2说明&#x…...

【MySQL】数据库之MHA高可用

目录 一、MHA 1、什么是MHA 2、MHA 的组成 3、MHA的特点 4、MHA的工作原理 二、有哪些数据库集群高可用方案 三、实操&#xff1a;一主两从部署MHA 1、完成主从复制 步骤一&#xff1a;完成所有MySQL的配置文件修改 步骤二&#xff1a;完成所有MySQL的主从授权&#x…...

ffmpeg 改变帧率,分辨率,时长等命令

ffmpeg -i elva.mp4 -ss 00:00:20 -t 00:00:30 -c:v copy -c:a copy output1.mp4 视频截取&#xff0c;开始时间和时长,-ss 00:00:20 -t 00:00:30 ffmpeg -i output1.mp4 -c:v libx265 output265.mp4 -c:v libx265,264转265 ffmpeg -i output1.mp4 -c:v libx264 output264.mp4 …...

烟火检测AI边缘计算智能分析网关V4在安防项目中的应用及特点

一、行业背景 随着社会和经济的发展&#xff0c;公共安全和私人安全的需求都在不断增长。人们需要更高效、更准确的安防手段来保障生命财产安全&#xff0c;而人工智能技术正好可以提供这种可能性&#xff0c;通过智能监控、人脸识别、行为分析等手段&#xff0c;大大提高了安防…...

有效的回文

常用方法就是双指针。使用两个指针从字符串的两端向中间移动&#xff0c;同时比较对应位置的字符&#xff0c;直到两个指针相遇。由于题目忽略非字母和非数字的字符且忽略大小写&#xff0c;所以跳过那些字符&#xff0c;并将字母转换为小写&#xff08;或大写&#xff09;进行…...

Electron快速上手

Electron 目录 简介 打包简单的html/css/javascript项目 打包Vue2项目 打包Vue3项目 简介 Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows…...

华为“纯血”鸿蒙加速进场 高校、企业瞄准生态开发新风口

近日&#xff0c;华为终端BG CEO、智能汽车解决方案BU董事长余承东在2024年新年信中提出&#xff0c;开启华为终端未来大发展的新十年。 他特别提到&#xff0c;未来要构建强大的鸿蒙生态&#xff0c;2024年是原生鸿蒙的关键一年&#xff0c;将加快推进各类鸿蒙原生应用的开发…...

抖音百科怎么创建?头条百科的规则和技巧

在玩抖音的时候&#xff0c;不知道注意到抖音的搜索结果没有&#xff0c;有时候会去搜索框搜索一个品牌或人物名称&#xff0c;搜索框下面翻几下大概率就会出现百科词条&#xff0c;这个词条就是抖音百科。抖音的百科属于头条百科&#xff0c;因为这两个平台都属于字节跳动旗下…...

leetcode10-困于环中的机器人

题目链接&#xff1a; https://leetcode.cn/problems/robot-bounded-in-circle/description/?envTypestudy-plan-v2&envIdprogramming-skills 思路&#xff1a; 首先&#xff0c;题目要寻找的是成环的情况。 1.如果经历一次指令后的方向仍为北方&#xff0c;要使得机器人循…...

Linux-shell简单学习

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 其他…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...