在Spring Boot项目中整合Redis:高效数据存储与缓存的最佳实践

目录

1. 引入依赖

2. 创建序列化配置类

2.1 序列化的选择

3. 配置YAML文件

3.1 连接池的配置

4. 使用Redis

4.1 复杂数据类型的存储

4.2 列表、集合和哈希的使用

4.2.1 列表示例

4.2.2 集合示例

4.2.3 哈希示例

5.  处理事务和管道

5.1 事务示例

5.2 管道示例

6.  Redis的过期策略与持久化

7.  Redis集群与分布式

8.  总结


在现代应用开发中,缓存技术的使用越来越普遍。Redis作为一个高性能的键值存储数据库,因其快速、灵活的特性被广泛应用于各种场景。无论是提升数据访问速度,还是减轻后端数据库的压力,Redis都能发挥重要作用。本文将详细介绍如何在Spring Boot项目中整合Redis,以实现高效的数据存储和缓存功能。

1. 引入依赖

首先,我们需要在pom.xml中引入Spring Boot和Redis相关的依赖。以下是必要的依赖配置:

<dependency>  <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-starter-data-redis</artifactId>  
</dependency>  
<dependency>  <groupId>com.fasterxml.jackson.datatype</groupId>  <artifactId>jackson-datatype-jsr310</artifactId>  <version>2.13.0</version>  
</dependency>

这些依赖将使我们能够使用Spring Data Redis来简化与Redis的交互。spring-boot-starter-data-redis提供了与Redis的基本集成,而jackson-datatype-jsr310则用于处理Java 8的日期和时间API。

2. 创建序列化配置类

在Redis中,数据的序列化和反序列化是非常重要的。我们需要创建一个配置类来定义如何序列化存储在Redis中的数据。以下是一个示例配置类:

package com.dahua.evo.event.business.redis.config;  import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.data.redis.connection.RedisConnectionFactory;  
import org.springframework.data.redis.core.RedisTemplate;  
import org.springframework.data.redis.serializer.StringRedisSerializer;  @Configuration  
public class ConfigRedis {  @Autowired  private RedisConnectionFactory redisConnectionFactory;  @Bean  public RedisTemplate<String, Object> redisTemplate() {  RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();  // 序列化key  redisTemplate.setKeySerializer(new StringRedisSerializer());  redisTemplate.setValueSerializer(new StringRedisSerializer());  // 序列化hash  redisTemplate.setHashKeySerializer(new StringRedisSerializer());  redisTemplate.setHashValueSerializer(new StringRedisSerializer());  // 连接redis数据库  redisTemplate.setConnectionFactory(redisConnectionFactory);  return redisTemplate;  }  
}

在这个配置类中,我们定义了一个RedisTemplate的Bean,并设置了键和值的序列化方式为StringRedisSerializer,这使得我们在存储和读取数据时更加方便。

2.1 序列化的选择

在选择序列化方式时,StringRedisSerializer适用于简单的字符串数据,但在处理复杂对象时可能不够灵活。可以考虑使用Jackson2JsonRedisSerializer,它支持将Java对象序列化为JSON格式,便于存储和读取复杂数据结构:

import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;  
import com.fasterxml.jackson.databind.ObjectMapper;  // ...  @Bean  
public RedisTemplate<String, Object> redisTemplate() {  RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();  // 使用Jackson序列化  Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);  ObjectMapper objectMapper = new ObjectMapper();  objectMapper.findAndRegisterModules();  serializer.setObjectMapper(objectMapper);  redisTemplate.setKeySerializer(new StringRedisSerializer());  redisTemplate.setValueSerializer(serializer);  redisTemplate.setHashKeySerializer(new StringRedisSerializer());  redisTemplate.setHashValueSerializer(serializer);  redisTemplate.setConnectionFactory(redisConnectionFactory);  return redisTemplate;  
}

3. 配置YAML文件

接下来,我们需要在application.yml中配置Redis的连接信息。以下是一个示例配置:

spring:  redis:  host: 10.56.11.34  port: 38235  password: 909a2c647  database: 7  client-name: vehicleService  lettuce:  pool:  max-active: 20  # 连接池最大连接数(使用负值表示没有限制)  max-wait: -1    # 最大阻塞等待时间(负数表示没有限制)  max-idle: 5     # 连接池中最大空闲连接  min-idle: 0     # 连接池中最小空闲连接

在这里,我们配置了Redis的主机、端口、密码和数据库索引,以及连接池的相关参数,以确保我们的应用能够高效地与Redis进行交互。

3.1 连接池的配置

使用连接池可以有效管理Redis连接,提升应用的性能。Lettuce是Spring Boot中默认的Redis客户端,支持异步和响应式编程。通过配置连接池参数,可以根据实际负载调整最大活动连接数、最大空闲连接数等,以确保在高并发场景下的稳定性。

4. 使用Redis

现在,我们可以在Spring Boot应用中使用Redis了。以下是一个简单的控制器示例,展示了如何使用RedisTemplate进行数据的存储和读取:

import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.web.bind.annotation.GetMapping;  
import org.springframework.web.bind.annotation.RestController;  import java.util.concurrent.TimeUnit;  @RestController  
public class TestController {  @Autowired  private RedisTemplate<String, Object> redisTemplate;  @GetMapping(value = "/test1")  public String getAllDevice1() {  this.redisTemplate.opsForValue().set("k1", "cnk", 30, TimeUnit.SECONDS);  System.out.println(this.redisTemplate.opsForValue().get("k1"));  return "test1";  }  
}

在这个示例中,我们使用opsForValue()方法将一个键值对存储到Redis中,并设置过期时间为30秒。然后,我们读取这个键的值并打印到控制台。

4.1 复杂数据类型的存储

在实际应用中,可能需要存储复杂数据类型,例如用户对象、订单信息等。可以直接将对象存储到Redis中,前提是使用合适的序列化方式。例如,假设我们有一个User类:

public class User {  private String id;  private String name;  private int age;  // getters and setters  
}

我们可以这样存储和读取:

// 读取对象  
User retrievedUser = (User) redisTemplate.opsForValue().get("user:1");  
if (retrievedUser != null) {  System.out.println("Retrieved User: " + retrievedUser.getName() + ", Age: " + retrievedUser.getAge());  
} else {  System.out.println("No user found with the key 'user:1'");  
}

4.2 列表、集合和哈希的使用

Redis支持多种类型的数据结构,这些结构在很多场景中都非常有用,比如:

  • 列表(List):用于存储多个有序的数据项。
  • 集合(Set):用于存储不重复的数据项。
  • 哈希(Hash):用于存储一个对象的多个属性。

下面分别给出示例使用方式。

4.2.1 列表示例
// 添加元素到列表  
redisTemplate.opsForList().leftPush("userQueue", user1);  
redisTemplate.opsForList().leftPush("userQueue", user2);  // 获取列表中的所有元素  
List<User> userList = redisTemplate.opsForList().range("userQueue", 0, -1);  
userList.forEach(user -> System.out.println("User from List: " + user.getName()));
4.2.2 集合示例
// 向集合中添加元素  
redisTemplate.opsForSet().add("userSet", user1, user2, user3);  // 检查用户是否在集合中  
Boolean exists = redisTemplate.opsForSet().isMember("userSet", user1);  
System.out.println("User exists in set: " + exists);
4.2.3 哈希示例
// 将用户对象的属性存储在哈希中  
redisTemplate.opsForHash().put("user:1", "name", "John Doe");  
redisTemplate.opsForHash().put("user:1", "age", 30);  // 获取哈希中的属性  
String name = (String) redisTemplate.opsForHash().get("user:1", "name");  
Integer age = (Integer) redisTemplate.opsForHash().get("user:1", "age");  
System.out.println("User Hash - Name: " + name + ", Age: " + age);

5.  处理事务和管道

Redis也支持事务和管道功能,这在需要执行一系列命令时非常有用,可以提高效率并保证原子性。

5.1 事务示例
// 开启一个事务  
List<Object> results = redisTemplate.executePipelined((redisOperations) -> {  redisOperations.opsForValue().set("key1", "value1");  redisOperations.opsForValue().set("key2", "value2");  return null;  
});  // 提交事务  
redisTemplate.exec();
5.2 管道示例

管道可以将多个Redis命令打包发送,提高批量操作的性能:

List<Object> executedResults = redisTemplate.executePipelined((operations) -> {  for (int i = 0; i < 10; i++) {  operations.opsForValue().set("pipelinedKey" + i, "value" + i);  }  return null;  
});  // 处理返回值  
System.out.println("Pipelined operations completed.");

6.  Redis的过期策略与持久化

Redis支持设置键的过期时间,对应于不再需要的数据可以被自动清除,节省存储空间。可以通过设置expire方法来实现这一功能:

redisTemplate.opsForValue().set("temporaryKey", "temporaryValue", 60, TimeUnit.SECONDS);

当需要持久化Redis中的数据时,可以选择RDBAOF(Append Only File)策略。RDB适用于定期快照,而AOF则适用于每次写操作后立即持久化,用户可以根据需求选择。

7.  Redis集群与分布式

随着微服务架构的流行,使用Redis集群可以帮助处理高并发和大流量请求。Redis集群将数据分片存储在不同节点中,实现横向扩展。如果要部署Redis集群,Spring Boot与Redis的集成也同样简单,只需将集群配置添加到application.yml中。

spring:  redis:  cluster:  nodes:  - 10.56.11.34:38235  - 10.56.11.35:38235  - 10.56.11.36:38235

8.  总结

通过以上步骤,我们成功地在Spring Boot项目中整合了Redis。这种整合不仅提高了数据的访问速度,还有效地减轻了数据库的压力。Redis的高性能和灵活性使其成为现代应用不可或缺的组成部分。

在本文中,我们深入探讨了如何在Spring Boot项目中使用Redis,详细讲解了不同数据结构的使用、序列化方式的选择、事务和管道的使用、以及Redis的过期策略与持久化方法。这些都是确保应用高效与稳定的关键。

希望这篇文章能够帮助你快速上手Spring Boot与Redis的整合,为你的项目增添更多的高效能和可扩展性。如果你对Redis的更多高级特性或在Spring Boot中的应用有兴趣,欢迎在评论区留言讨论,或与我进一步探讨。

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

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

相关文章

嵌入式硬件设计 — 智能设备背后的隐形架构大师

目录 引言 一、嵌入式硬件设计概述 &#xff08;一&#xff09;需求分析 &#xff08;二&#xff09;硬件选型 &#xff08;三&#xff09;电路设计 &#xff08;四&#xff09;PCB 制作与焊接 &#xff08;五&#xff09;硬件调试与测试 &#xff08;六&#xff09;软…

调度系统:使用 Airflow 对 Couchbase 执行 SQL 调度时的潜在问题

使用 Airflow 对 Couchbase 执行 SQL 调度时&#xff0c;通常情况下不会直接遇到与 Couchbase 分布式特性相关的异常&#xff0c;但在某些特定情境下&#xff0c;可能会出现一些与分布式环境、调度和数据一致性相关的潜在问题。以下是一些可能会遇到的问题和建议的解决方案&…

[大数据]Hudi编译集成

1. Hudi概述 1.1 Hudi简介 What is Apache Hudi Apache Hudi is the next generation streaming data lake platform. Apache Hudi brings core warehouse and database functionality directly to a data lake. Hudi provides tables, transactions, efficient upserts/dele…

windows下 mysql开启 binlog日志

一、查看是否开启 binlog -- 方式一 show binary logs;-- 方式二 show VARIABLES like log_bin 说明没有开启 方式一 &#xff1a;you are not using binary logging 方式二&#xff1a;log_bin off 二、编辑 my.ini 配置文件 默认安装地点位于&#xff1a;C:\ProgramDat…

本题要求采用选择法排序,将给定的n个整数从大到小排序后输出。

#include <stdio.h> #define MAXN 10 int main() { int i, index, k, n, temp; int a[MAXN]; scanf("%d", &n); for (i 0; i < n; i) { scanf("%d", &a[i]); } // 外层循环控制排序轮数&#xff0c;一共需要n-1轮 for (k 0; k < n…

Vue.js的生命周期

Vue.js 是一个构建用户界面的渐进式框架&#xff0c;它提供了一个响应式和组件化的方式来构建前端应用。了解 Vue 的生命周期对于开发者来说至关重要&#xff0c;因为它可以帮助我们更好地控制组件的状态和行为。本文将详细介绍 Vue 的生命周期&#xff0c;并提供相应的代码示例…

Java-22 深入浅出 MyBatis - 手写ORM框架3 手写SqlSession、Executor 工作原理

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…

Android 逆向/反编译/Hook修改应用行为 基础实现

前言&#xff1a;本文通过一个简单的情景案例实现安卓逆向的基本操作 一、情景描述 本文通过一个简单的情景案例来实现安卓逆向的基本操作。在这个案例中所使用的项目程序是我自己的Demo程序&#xff0c;不会造成任何的财产侵害&#xff0c;本文仅作为日常记录及案例分享。实…

IDEA创建Spring Boot项目配置阿里云Spring Initializr Server URL【详细教程-轻松学会】

1.首先打开idea选择新建项目 2.选择Spring Boot框架(就是选择Spring Initializr这个) 3.点击中间界面Server URL后面的三个点更换为阿里云的Server URL Idea中默认的Server URL地址&#xff1a;https://start.spring.io/ 修改为阿里云Server URL地址&#xff1a;https://star…

基于MATLAB的信号处理工具:信号分析器

信号&#xff08;或时间序列&#xff09;是与特定时间相关的一系列数字或测量值&#xff0c;不同的行业和学科将这一与时间相关的数字序列称为信号或时间序列。生物医学或电气工程师会将其称为信号&#xff0c;而统计学家或金融定量分析师会使用时间序列这一术语。例如&#xf…

Plugin - 插件开发03_Spring Boot动态插件化与热加载

文章目录 Pre方案概览使用插件的好处流程CodePlugin 定义Plugin 实现Plugin 使用方动态加载插件类加载器注册与卸载插件配置文件启动类测试验证 小结 Pre 插件 - 通过SPI方式实现插件管理 插件 - 一份配置&#xff0c;离插件机制只有一步之遥 插件 - 插件机制触手可及 Plug…

ECharts柱状图-阶梯瀑布图,附视频讲解与代码下载

引言&#xff1a; 在数据可视化的世界里&#xff0c;ECharts凭借其丰富的图表类型和强大的配置能力&#xff0c;成为了众多开发者的首选。今天&#xff0c;我将带大家一起实现一个柱状图图表&#xff0c;通过该图表我们可以直观地展示和分析数据。此外&#xff0c;我还将提供…

【Hash Function and HashMap】

散列函数&#xff08;Hash Function&#xff09;是一种将任意大小的数据映射到固定大小值的函数。在 HashMap 中&#xff0c;它扮演着核心角色。让我详细解释&#xff1a; 散列函数基本原理 输入&#xff1a;任意类型的键&#xff08;key&#xff09;输出&#xff1a;固定大小…

【jvm】为什么要有GC

目录 1. 自动内存管理2. 提升程序稳定性3. 优化性能4. 跨平台能力5. 分代回收策略 1. 自动内存管理 1.JVM中的GC机制负责自动管理内存&#xff0c;这意味着开发人员不需要手动分配和释放内存。2.这一特性大大简化了Java程序的内存管理&#xff0c;降低了内存泄漏和内存溢出等问…

Python泛型编程:TypeVar和Generic详解 - 写给初学者的指南

Python泛型编程&#xff1a;TypeVar和Generic详解 - 写给初学者的指南 前言1. 为什么需要泛型&#xff1f;2. TypeVar&#xff1a;定义泛型类型变量3. Generic&#xff1a;创建泛型类4. 多个泛型类型变量5. 使用场景小结结语 前言 大家好&#xff01;今天我们来聊一聊Python中…

COUNT(*)、COUNT(1)、COUNT(某一列)的区别是什么?哪个性能更好

一些特殊情况&#xff1a; 有索引时&#xff1a;如果查询使用了索引&#xff0c;且查询的列在索引中&#xff0c;COUNT(某一列) 可能在某些情况下会比较快&#xff0c;因为数据库只需要扫描索引&#xff0c;而不需要扫描整个表。有 NULL 值时&#xff1a;COUNT(某一列) 可能会…

C/C++流星雨

系列文章 序号直达链接1C/C爱心代码2C/C跳动的爱心3C/C李峋同款跳动的爱心代码4C/C满屏飘字表白代码5C/C大雪纷飞代码6C/C烟花代码7C/C黑客帝国同款字母雨8C/C樱花树代码9C/C奥特曼代码10C/C精美圣诞树11C/C俄罗斯方块12C/C贪吃蛇13C/C孤单又灿烂的神-鬼怪14C/C闪烁的爱心15C/C…

【机器学习】——K均值聚类:揭开数据背后的隐藏结构

目录 引言&#xff1a;什么是聚类分析&#xff1f;K均值聚类的基本原理 2.1 聚类的概念2.2 K均值聚类简介 K均值算法的工作原理 3.1 初始化与选定K值3.2 计算距离与分配簇3.3 更新质心3.4 迭代与收敛 K均值聚类的优缺点 4.1 优点4.2 缺点与局限性 K均值聚类的常见应用 5.1 市场…

【WRF-Urban】SLUCM新增空间分布城市冠层参数及人为热排放AHF代码详解(下)

目录 详细解释更改文件内容4 运行模块(run):README.namelist5 输出模块(share):share/module_check_a_mundo.Fshare/output_wrf.F参考SLUCM新增空间分布城市冠层参数及人为热排放AHF代码详解的前两部分内容可参见-【WRF-Urban】SLUCM新增空间分布城市冠层参数及人为热排放A…

go 集成nacos注册中心、配置中心

使用限制 Go>v1.15 Nacos>2.x 安装 使用go get安装SDK&#xff1a; go get -u github.com/nacos-group/nacos-sdk-go/v2 快速使用 初始化客户端配置ClientConfig constant.ClientConfig{TimeoutMs uint64 // 请求Nacos服务端的超时时间&#xff0c;默…