SpringDataRedis简介

SpringDataSpring中专门进行数据操作的模块,包含了对于各种数据库的集成。其中对Redis的集成模块叫做SpringDataRedis(官网地址:Spring Data Redis)。其最核心的特点就是提供了不同Redis客户端的整合:结合了JedisLettuce提供了RedisTemplate这个统一的操作模板来操作Redis,下图是SpringDataRedis的其他特点:
在这里插入图片描述

由于Spring系列的强大生态支持,和SpringDataRedis本身优秀的使用体验,现在越来越多的企业倾向于使用SpringDataRedis作为RedisJava客户端,同时本人也推荐大家使用SpringDataRedis

SpringDataRedis快速入门

引入依赖

我们使用SpringBoot框架来进行SpringBootRedis的快速入门。由于SpringBoot已经提供了对SpringDataRedis的支持(可以在创建SpringBoot项目的时候将SpringDataRedis的依赖引入到pom.xml文件中),所以说使用起来非常的简单,如果没有在创建项目时引入依赖,也可以进行手动引入,在引入时不但需要SpringDataRedis的依赖,还需要一个连接池依赖来实现连接池(commons-pool2):

<!-- SpringDataRedis依赖 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>3.4.6</version>
</dependency>
<!-- 连接池依赖 -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.12.0</version>
</dependency>

配置文件

因为我们使用了SpringBoot框架,所以说对于Redis连接的配置我们可以直接基于application文件进行配置:

spring:data:redis:host: 192.168.181.134port: 6379password: your password# 连接池配置lettuce:pool:max-active: 8 # 最大连接数max-idle: 8 # 最大空闲连接min-idle: 4 # 最小空闲连接max-wait: 1000ms # 连接等待时间

在配置连接池的时候需要特别注意,可以使用JedisLettuce两个连接池: 在这里插入图片描述
Spring默认使用的是Lettuce连接池,可以从Maven依赖传递中看出:
在这里插入图片描述

而我们并没有引入Jedis的依赖,所以说在配置连接池的时候使用Lettuce即可,如果想要使用Jedis连接池,则需要引入对应的依赖。

编码操作

上文提到了SpringDataRedis提供了一个RedisTemplate这个统一的操作模板来操作Redis,所以说想要使用SpringDataRedis只需要学会RedisTemplate即可RedisTemplate中封装了各种对于Redis的操作,并且将不同数据类型的操作API封装到了不同的类型中:
在这里插入图片描述

下面是一个简单的RedisTemplate操作示例:

package com.wzb;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;@SpringBootTest
class RedisSpringDataApplicationTests {@Autowiredprivate RedisTemplate redisTemplate;@Testvoid testString() {// 存储一条String数据redisTemplate.opsForValue().set("name", "jack");// 获取String数据Object name = redisTemplate.opsForValue().get("name");System.out.println(name);}}

这是一个SpringBoot的测试类,其中通过@Autowired注解注入了RedisTemplate,然后在测试方法中,通过opsForValue来操作String类型的数据,并且通过set方法存入一条KeynameValuejack的数据。但是这样存入数据之后,我们是无法正常读取的,让我们通过可视化界面查看一下刚才存入的数据:
在这里插入图片描述
在这里插入图片描述

我们可以看到在我们原本的Key:name之间有一大串字符,在原本的Value:jack之前也有一大串字符。这是因为RedisTemplate在存入数据之前需要将数据序列化,而默认的序列化器是JdkSerializationRedisSerializer也就是JDK的默认序列化器,该序列化器会将Java对象转换为Java标准的二进制序列化,而那些十六进制的特殊字符是JDK序列化的魔法数。这样的状况显然不是我们想看到的,因为这样的话存入的Key-Value的值完全被改变了,无法直接进行读取或修改,此时,就需要配置RedisTemplate的序列化器。

配置RedisTemplate的序列化器

在这里插入图片描述

通过观察RedisTemplate的源代码发现,RedisTemplate一共可以支持4个序列化器的配置,并且由于这4个序列化器的配置都是null,所以说会使用默认的JdkSerializationRedisSerializer序列化器。可供选择的Serializer如图所示:
在这里插入图片描述
在这里插入图片描述

一般对于Key的序列化会使用StringRedisSerializer,而Value的序列化器使用 genericJackson2JsonRedisSerializer这个序列化器会将Java对象转为Json字符串然后再存储到Redis中。
我们可以创建一个类来完成RedisTemplate的序列化器配置:

package com.wzb.config;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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;/*** Redis序列化设置*/
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {// 创建RedisTemplate对象RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();// 设置连接工厂redisTemplate.setConnectionFactory(redisConnectionFactory);// 创建Json序列化工具GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();// 设置Key序列化redisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setHashKeySerializer(RedisSerializer.string());// 设置Value序列化redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);// 返回return redisTemplate;}}

想要使用genericJackson2JsonRedisSerializer序列化器还需要引入Json相关依赖:

<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId>
</dependency>

然后就可以修改原来代码,注入我们自定义序列化器的RedisTemplate

@Autowired
private RedisTemplate<String, Object> redisTemplate;

测试之后发现,存入的数据是我们想要的结果:
在这里插入图片描述

然后测试存入一个Java对象:

@Test
void testObject() {redisTemplate.opsForValue().set("user", new User("zhangsan", 20));User user = (User)redisTemplate.opsForValue().get("user");System.out.println(user);
}

在这里插入图片描述
在这里插入图片描述

发现存取都是没有问题的,更换RedisTemplate序列化器成功。

StringRedisTemplate

在使用genericJackson2JsonRedisSerializer序列化器存储一个Java对象时,除了对象的属性外,还会存储这个类的全类名以便于反序列化。这样看似很方便,但实际上存在一个很大的问题:耗费了太多的额外存储空间。因为Redis是基于内存的,众所周知,内存是十分宝贵的,所以说要尽量高效地使用内存,将全类名存入Redis是不推荐的做法。
解决方法就是对于Value,也使用和Key一样的StringRedisSerializer序列化器,Value当作String类型进行处理,然后在Java代码中通过程序手动序列化和反序列化Spring早就为我们考虑到了这一点,于是提供了一个StringRedisTemplate工具,其KeyValue的序列化器就是StringRedisSerializer

在这里插入图片描述
我们就可以使用StringRedisTemplate来操作,而无需自己去设置序列化器:

package com.wzb;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wzb.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.StringRedisTemplate;import java.util.Map;@SpringBootTest
public class StringRedisTemplateTests {@Autowiredprivate StringRedisTemplate stringRedisTemplate;private static final ObjectMapper mapper = new ObjectMapper();@Testvoid testSave() throws JsonProcessingException {// 创建对象User user = new User("lisi", 25);// 手动序列化String json = mapper.writeValueAsString(user);// 写入数据stringRedisTemplate.opsForValue().set("user", json);// 获取数据String jsonUser = stringRedisTemplate.opsForValue().get("user");// 手动反序列化User readUser = mapper.readValue(jsonUser, User.class);System.out.println(readUser);}}

使用了StringRedisTemplate之后,需要我们手动进行对象的序列化和反序列化,其他的操作和使用RedisTemplate并无差别,但是这样之后,存储一个Java对象就不会再存储其字节码等额外信息了:

在这里插入图片描述

这样做会增加额外的代码处理,但是可以极大的节约内存资源,是推荐的做法。

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

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

相关文章

B. Shrinking Array/缩小数组

B. Shrinking Array让我们称一个数组 b 为 i 美丽 &#xff0c;如果它至少包含两个元素&#xff0c;并且存在一个位置 |bi−bi1|≤1 使得 |x| (其中 x 是 #10# #11# 的绝对值)。给定一个数组 a &#xff0c;只要它至少包含两个元素&#xff0c;你就可以执行以下操作&#xff1a…

【学习笔记】Linux系统中SSH服务安全配置

一、背景知识 以ubuntu为例&#xff0c;查看ssh服务是否安全并配置&#xff0c;执行 ssh -V ssh的配置文件路径&#xff1a;/etc/ssh/sshd_config 二、SSH服务配置文件 1.端口和监听设置 Port 22 含义&#xff1a;指定SSH服务监听的端口号&#xff08;默认是22&#xff09…

FastAPI + Tortoise-ORM + Aerich 实现数据库迁移管理(MySQL 实践)

在 FastAPI 项目中&#xff0c;Tortoise-ORM 是一个轻量的异步 ORM 框架&#xff0c;适用于 async/await 场景。结合数据库迁移工具 Aerich&#xff0c;可以优雅地管理数据库表结构演进&#xff0c;本文将通过完整流程演示如何在 MySQL 环境下使用。&#x1f4e6; 一、环境准备…

7.7日 实验03-Spark批处理开发(2)

使用Spark处理数据文件检查数据检查$DATA_EXERCISE/activations里的数据&#xff0c;每个XML文件包含了客户在指定月份活跃的设备数据。拷贝数据到HDFS的/dw目录样本数据示例&#xff1a;<activations><activation timestamp"1225499258" type"phone&q…

C语言可变参数感悟

#include <stdio.h> #include <stdarg.h> #if 1 /* *在C语言中&#xff0c;可变参函数是指参数数量不固定的函数&#xff0c;比如printf\scanf *可变参函数的语法&#xff1a; *返回类型 函数名&#xff08;固定函数&#xff0c;.....) { //函数体 } *1、包含头文件…

LeetCode 1248.统计优美子数组

给你一个整数数组 nums 和一个整数 k。如果某个连续子数组中恰好有 k 个奇数数字&#xff0c;我们就认为这个子数组是「优美子数组」。 请返回这个数组中 「优美子数组」 的数目。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,2,1,1], k 3 输出&#xff1a;2 解释&#xf…

FastAPI Docker环境管理脚本使用指南

作者: 源滚滚AI编程 创建时间: 2025年07月08日 版本: v1.0.0 文档状态: 完成 版权声明 本文档由源滚滚AI编程创作,版权所有。未经作者书面许可,不得复制、分发或用于商业用途。 免责声明 本文档仅用于技术交流和学习目的。作者不对使用本文档内容导致的任何问题承担责任。…

前端常见 HTTP 状态码

作为前端开发者&#xff0c;与后端 API 交互时&#xff0c;HTTP 状态码是判断请求成败的关键信号。理解常见状态码的含义、责任归属及应对策略&#xff0c;能极大提升调试效率和团队协作。以下是关键状态码的详细解析&#xff1a; 首先说一下如何查看状态码&#xff1a; 如上图…

深度解析C语言内存函数(小米面试题)

目录 一、memcpy1.1 代码演示1.2 memcpy的模拟实现 二、memmove2.1 代码演示2.2 模拟实现&#xff08;小米面试题&#xff09; 三、memset3.1 代码演示3.2 总结 四、memcmp4.1 代码演示4.2 总结 总结 一、memcpy &#xff08;memory copy 内存复制&#xff09; 之前文章中写的…

DK124反激式开关电源芯片

18W 高性能交直流转换芯片 特性 DK124 是一款离线式开关电源芯片&#xff0c;最大输出功率达到 24W。内部集成了 PWM 控制器、700V 功率管和初级峰值电流检测电路&#xff0c;并采用了可以省略辅助供电绕组的专利自供电技术&#xff0c;极大简化了外围应用电路&#xff0c;减…

商品销售数据分析实验

进入虚拟机&#xff0c;启动HDFS和Yarn1.创建表 hive show databases; use test;销售订单表create table t_dml (detail_id bigint,sale_date date, province string,city string,product_id bigint,cnt bigint,amt double )row format delimited fields terminated by ,;商品…

PH热榜 | 2025-07-08

1. TensorBlock Forge 标语&#xff1a;人工智能模型的API 介绍&#xff1a;Forge是一个快速且安全的工具&#xff0c;让你可以跨不同供应商连接和运行AI模型 产品网站&#xff1a; 立即访问 Product Hunt&#xff1a; View on Product Hunt 票数&#xff1a; &#x1f53a…

2025-01)electronjs-v11.2.0升级到新版本electronjs-v37.2.0记录,node版本记录,淘宝镜像配置记录,升级记录

背景:由于22年使用electronjs开发的自助机客户端几年没去维护,现在有需求要修改,电脑也换新了,node环境也没,直接把electron从 之前的 11.2.0 版本 升级到了37.2.0版本,升级最主要的目的是升级谷歌浏览器内核,升级后谷歌浏览器内核直接从87升级到了138,可以支持谷歌最新…

iQOO手机怎样相互远程控制?其他手机可以远程控制iQOO吗?

iQOO是Vivo同一品牌下的产品&#xff0c;它们两款手机都可以使用手机内置的远程控制功能。具体做法是&#xff0c;打开控制端的iQOO手机的【设置】【快捷与辅助】、【远程协助】&#xff0c;然后输入被控端的电话号码&#xff0c;等被控端的手机接受远程协助后&#xff0c;就可…

【入门级-C++程序设计:3、程序基本语句-多层循环语句】

1、定义&#xff1a; 在 C 中&#xff0c;多层循环&#xff08;嵌套循环&#xff09;是指在一个循环体内包含另一个或多个循环语句。它常用于处理多维数据结构&#xff08;如二维数组&#xff09;、复杂的迭代逻辑&#xff08;如矩阵运算、图形打印、组合遍历等&#xff09;。多…

四、jenkins自动构建和设置邮箱

一、jenkins自动构建什么自动构建、有啥用&#xff1a;触发方式代码提交&#xff08;Git push&#xff09;定时任务&#xff08;如每天凌晨构建&#xff09;手动点击等方式&#xff08;立即执行&#xff09;执行内容从 Git/SVN 拉取最新代码运行编译&#xff08;如 Maven/Gradl…

【深度学习新浪潮】深入解析LLM关键概念:架构、优化与最新研究进展

1. Transformer架构与注意力机制 概念解析 Transformer是LLM的核心架构,由编码器和解码器组成,其核心创新是自注意力机制,通过计算输入序列中每个位置的关联权重,动态聚焦关键信息。自注意力机制的计算复杂度为O(n),在处理长序列时成为性能瓶颈。 代码示例:基础Transfo…

RAGflow图像解析与向量化分析

RAGflow图像解析与向量化分析 注:需要提前部署好ragflow,才方便一 一对应代码,部署教程:rag部署教程,这样才会方便后续更改 1. 图像解析流程 RAGflow通过多种解析器处理不同类型的文档,其中图像解析是一个重要组成部分。以下是RAGflow处理图像的主要流程: 1.1 PDF文…

千翼破界,百景赋能 | 2025深圳eVTOL展无人机场景应用专场即将启幕

在技术革新、应用深化、产业链协同升级及低空空域管理改革等多重政策红利驱动下&#xff0c;我国工业级无人机产业正迈入爆发式增长新阶段&#xff0c;持续引领民用无人机市场繁荣。数据显示&#xff0c;2019 至2024年&#xff0c;我国民用无人机市场规模从435.1亿元跃升至1108…

Go语言标识符命名规则详解:工程化实践

引言 Go语言的命名规则是其简洁哲学和工程实用性的集中体现。下面从语法规范、最佳实践到实际应用进行全面解析&#xff1a; 一、基础命名规则 1. 变量命名 // 小驼峰式&#xff08;lowerCamelCase&#xff09; var userName string var maxRetryCount 3 var isConnected bool…