Redis从入门到精通(三)Jedis客户端、SpringDataRedis客户端

文章目录

  • 前言
  • 第3章 Redis的Java客户端
    • 3.1 Jedis客户端
      • 3.1.1 快速使用
      • 3.1.2 连接池
    • 3.2 SpringDataRedis客户端
      • 3.2.1 快速使用
      • 3.2.2 自定义序列化
      • 3.2.3 StringRedisTemplate
    • 3.3 小结

前言

在上一章【Redis从入门到精通(二)Redis的数据类型和常见命令介绍】中,学习了Redis的五种基本数据类型,即String、Hash、List、Set、SortedSet类型,及其常用的命令。

这一节学习Redis的两种Java客户端:Jedis和SpringDataRedis。

第3章 Redis的Java客户端

3.1 Jedis客户端

Jedis是Redis的一个Java客户端,旨在提高性能和易用性。 Jedis的官网地址:https://github.com/redis/jedis。

3.1.1 快速使用

  • 1)创建一个maven项目,引入jedis依赖:
<!--jedis-->
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</version>
</dependency>
<!--单元测试-->
<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.7.0</version><scope>test</scope>
</dependency>
  • 2)编写单元测试
public class JedisTest01 {private Jedis jedis;@Beforepublic void setUp() {// 1.建立连接jedis = new Jedis("192.168.146.128", 6379);// 2.设置密码jedis.auth("123321");// 3.选择库jedis.select(0);}@Testpublic void testJedis() {// 存入String类型数据String result = jedis.set("myPro:user", "马老板");System.out.println("result = " + result);// 获取String类型数据String user = jedis.get("myPro:user");System.out.println("user = " + user);// 存入Hash类型数据Long result2 = jedis.hset("myPro:book", "name", "《三体1:地球往事》");System.out.println("result2 = " + result2);// 获取Hash类型数据String name = jedis.hget("myPro:book", "name");System.out.println("name = " + name);}@Afterpublic void cleanUp() {if(jedis != null) {jedis.close();}}
}
  • 3)执行单元测试
result = OK
user = 马老板
result2 = 1
name = 《三体1:地球往事》

在桌面客户端查看数据:

3.1.2 连接池

Jedis本身是线程不安全的,并且频繁地创建和销毁连接会有性能损耗,因此推荐使用Jedis连接池代替Jedis直连。

下面创建一个Jedis连接工厂,保存Jedis连接池:

public class JedisConnectionFactory {private static JedisPool jedisPool;static {// 配置连接池JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();// 最大连接数jedisPoolConfig.setMaxTotal(8);// 最大空闲连接数jedisPoolConfig.setMaxIdle(8);// 最小空现连接数jedisPoolConfig.setMinIdle(0);// 连接用尽后,最大等待时间(毫秒)jedisPoolConfig.setMaxWaitMillis(1000);// 创建连接池对象,参数分别是:配置信息、服务端IP、端口、超时时间(毫秒)、密码jedisPool = new JedisPool(jedisPoolConfig, "192.168.146.128", 6379, 1000, "123321");}public static Jedis getJedis() {return jedisPool.getResource();}
}

在单元测试中,可以改成从连接池中获取Jedis对象:

@Before
public void setUp() {// 1.建立连接// jedis = new Jedis("192.168.146.128", 6379);// 改用连接池方式获取Jedis对象jedis = JedisConnectionFactory.getJedis();// 2.设置密码jedis.auth("123321");// 3.选择库jedis.select(0);
}

3.2 SpringDataRedis客户端

SpringData是Spring中的数据操作模块,包含对各种数据库操作的集成,其中对Redis的集成模块就叫做SpringDataRedis。 官网地址是:https://spring.io/projects/spring-data-redis。

在官网文档中,列出了SpringDataRedis的主要特点:

  • 提供了对不同Redis客户端的整合(Lettuce和Jedis)
  • 提供了RedisTemplate工具类来统一操作Redis
  • 支持Redis的发布订阅模型
  • 支持Redis哨兵模式和集群模式
  • 支持基于Lettuce的响应式编程
  • 支持基于JDK、JSON、字符串、Spring对象的数据序列化和反序列化
  • 支持基于Redis的JDK Collection实现

对开发人员来说,最需要关注的是RedisTemplate工具类,它封装了各种对Redis的操作API:

3.2.1 快速使用

SpringBoot已经提供了对SpringDataRedis的支持,因此可以通过SpringBoot项目类使用SpringDataRedis。

  • 1)创建一个SpringBoot项目,引入相关依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.11.RELEASE</version></parent><groupId>com.star.redis</groupId><artifactId>redis_learning_spring</artifactId><version>1.0-SNAPSHOT</version><dependencies><!--redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!--commons-pool--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><!--json--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--test--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>
</project>
  • 2)在src/test/resources目录下新建配置文件application.yml,配置Redis相关信息:
spring:redis:host: 192.168.146.128port: 6379password: 123321lettuce:pool:max-active: 8max-idle: 8min-idle: 0max-wait: 1000
  • 3)在src/main/java目录下新建SpringBoot主启动类
@SpringBootApplication
public class MyApp {public static void main(String[] args) {SpringApplication.run(MyApp.class, args);}
}
  • 4)在src/test/java目录下新建测试类RedisSpringTest,编写单元测试
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyApp.class)
public class RedisSpringTest {@Autowiredprivate RedisTemplate redisTemplate;@Testpublic void test() {// 添加String类型数据redisTemplate.opsForValue().set("mySpring:name", "孙悟空");// 获取String类型数据Object name = redisTemplate.opsForValue().get("mySpring:name");System.out.println("name = " + name);}}

最终的项目结构如下:

  • 5)执行单元测试
name = 孙悟空

3.2.2 自定义序列化

在上面的案例中,redisTemplate.opsForValue().set()方法的两个参数的类型均为Object,在写入Redis之前会把Object序列化为字节形式(默认采用JDK序列化),取出时又会反序列化。因此在Redis中保存的数据是这样的:

缺点比较明显:可读性差、内存占用较大。

为此,可以通过自定义RedisTemplate的序列化方法解决这个问题。

在项目中新建一个配置类RedisConfig:

@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {// 创建RedisTemplate对象RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();// 设置连接工厂redisTemplate.setConnectionFactory(redisConnectionFactory);// 创建JSON序列化工具GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();// 设置Key的序列化redisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setHashKeySerializer(RedisSerializer.string());// 设置Value的序列化redisTemplate.setValueSerializer(jsonRedisSerializer);redisTemplate.setHashValueSerializer(jsonRedisSerializer);// 返回return redisTemplate;}
}

新建一个实体对象User:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {private String name;private Integer age;private Date birthday;
}

编写一个单元测试:

@Test
public void testJson() {// 添加String类型数据User user = new User("猪八戒", 500, new Date());redisTemplate.opsForValue().set("mySpring:user", user);// 获取String类型数据User user1 = (User) redisTemplate.opsForValue().get("mySpring:user");System.out.println(user1);
}

执行单元测试:

User(name=猪八戒, age=500, birthday=Sun Mar 31 14:48:27 CST 2024)

可见,在将User对象存入Redis时,会自动的序列化为JSON字符串,查询时也会自动地反序列化为Java对象。整体可读性有了很大的提升。

但要注意,序列化后的数据保存了Java对象对应的Class名称,目的是为了查询时实现自动地反序列化,但这会带来额外的内存开销。

3.2.3 StringRedisTemplate

使用JSON序列化器来处理Value值,会将class信息写入Redis,带来额外的内存开销。

要解决这个问题,可以统一使用String序列化器,也就是Key和Value值都只能使用String类型。这样意味着Java对象的序列化和反序列化需要手动实现。

这种用法比较普遍,因此SpringDataRedis就已经提供了一个RedisTemplate的子类:StringRedisTemplate,它的Key和Value值都采用String类型的序列化方式。

源码:org.springframework.data.redis.core.StringRedisTemplatepublic class StringRedisTemplate extends RedisTemplate<String, String> {public StringRedisTemplate() {setKeySerializer(RedisSerializer.string());setValueSerializer(RedisSerializer.string());setHashKeySerializer(RedisSerializer.string());setHashValueSerializer(RedisSerializer.string());}
}

在代码中可以直接使用StringRedisTemplate,例如:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyApp.class)
public class StringRedisTemplateTest {@Autowiredprivate StringRedisTemplate stringRedisTemplate;private static final ObjectMapper mapper = new ObjectMapper();@Testpublic void testSaveUser() throws JsonProcessingException {User user = new User("唐僧", 98, new Date());// 手动序列化String json = mapper.writeValueAsString(user);// 写入数据stringRedisTemplate.opsForValue().set("mySpring:user:200", json);// 获取数据String jsonUser = stringRedisTemplate.opsForValue().get("mySpring:user:200");// 手动反序列化User user1 = mapper.readValue(jsonUser, User.class);System.out.println(user1);}
}

执行单元测试:

User(name=唐僧, age=98, birthday=Sun Mar 31 15:02:25 CST 2024)

3.3 小结

第3章到此就学习完毕了,本章的主题是:Redis的Java客户端。回顾一下本章的学习的内容:

(三)Jedis客户端、SpringDataRedis客户端

更多内容请查阅分类专栏:Redis从入门到精通

第4章主要学习:Redis实战项目:短信登录

感兴趣的读者还可以查阅我的另外几个专栏:

  • SpringBoot源码解读与原理分析(已完结)
  • MyBatis3源码深度解析(已完结)
  • 再探Java为面试赋能(持续更新中…)

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

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

相关文章

Springboot+MybatisPlus+EasyExcel实现文件导入数据

记录一下写Excel文件导入数据所经历的问题。 springboot提供的文件处理MultipartFile有关方法&#xff0c;我没有具体看文档&#xff0c;但目测比较复杂&#xff0c; 遂了解学习了一下别的文件上传方法&#xff0c;本文第1节记录的是springboot原始的导入文件方法写法&#xf…

docker-compse安装es(包括IK分词器扩展)、kibana、libreoffice

Kibana是一个开源的分析与可视化平台&#xff0c;设计出来用于和Elasticsearch一起使用的。你可以用kibana搜索、查看存放在Elasticsearch中的数据。 Kibana与Elasticsearch的交互方式是各种不同的图表、表格、地图等&#xff0c;直观的展示数据&#xff0c;从而达到高级的数据…

MySQL 优化及故障排查

目录 一、mysql 前置知识点 二、MySQL 单实例常见故障 故障一 故障二 故障三 故障四 故障五 故障六 故障七 故障八 三、MySQL 主从故障排查 故障一 故障二 故障三 四、MySQL 优化 1.硬件方面 &#xff08;1&#xff09;关于 CPU &#xff08;2&#xff09;关…

Reversing Linked List

Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K3, then you must output 3→2→1→6→5→4; if K4, you must output 4→3→2→1→5→6. Input Specifi…

网络基础——ISIS

名词 ISIS&#xff1a;中间系统到中间系统&#xff0c;优先级是15集成化ISIS&#xff1a;这是在优化后&#xff0c;可以使用在OSI模型上的NET地址&#xff1a;由区域ID、系统ID和SEL组成&#xff0c;一台设备上最多配置3个NET地址&#xff0c;条件是区域号要不一致&#xff0c;…

Intel FPGA (7):adc adc128s102

Intel FPGA (7)&#xff1a;adc adc128s102 前提摘要 个人说明&#xff1a; 限于时间紧迫以及作者水平有限&#xff0c;本文错误、疏漏之处恐不在少数&#xff0c;恳请读者批评指正。意见请留言或者发送邮件至&#xff1a;“Email:noahpanzzzgmail.com”。本博客的工程文件均存…

用Python实现办公自动化(自动化处理PDF文件)

自动化处理 PDF 文件 目录 自动化处理 PDF 文件 谷歌浏览器 Chrome与浏览器驱动ChromeDriver安装 &#xff08;一&#xff09;批量下载 PDF 文件 1.使用Selenium模块爬取多页内容 2.使用Selenium模块下载PDF文件 3.使用urllib模块来进行网页的下载和保存 4.使用urllib…

关于OcenaBase v4.2中,分区转移和负载均衡的技术解读

OceanBase​​​​​​​​​​​​​​作为一款原生分布式数据库&#xff0c;其核心的技术特性之一是高可扩展性&#xff0c;其具体表现在两个方面&#xff1a; 首先&#xff0c;是灵活的扩缩容能力&#xff0c;包括垂直扩缩容和水平扩缩容&#xff1a; 垂直扩缩容&#xff…

神经网络汇聚层

文章目录 最大汇聚层平均汇聚层自适应平均池化层 最大汇聚层 汇聚窗口从输入张量的左上角开始&#xff0c;从左往右、从上往下的在输入张量内滑动。在汇聚窗口到达的每个位置&#xff0c;它计算该窗口中输入子张量的最大值或平均值。计算最大值或平均值是取决于使用了最大汇聚…

RISC-V/ARM mcu OpenOCD 调试架构解析

Risc-v/ARM mcu OpenOCD 调试架构解析 最近有使用到risc-v的单片机&#xff0c;所以了解了下risc-v单片机的编译与调试环境的搭建&#xff0c;面试时问到risc-v的调试可参看以下内容。 risc-v根据官方的推荐&#xff0c;调试器服务是选择OpenOCD&#xff0c;DopenOCD(开放片上…

Python反爬案例——验证码的识别

验证码的识别 使用打码平台识别验证码 利用打码平台可以轻松识别各种各样的验证码&#xff0c;图形验证码、滑动验证码、点选验证码和逻辑推理验证码。打码平台提供了一系列API&#xff0c;只需要向API上传验证码图片&#xff0c;它便会返回对应的识别结果。 使用超级鹰平台…

深入理解指针1:指针变量、指针运算、野指针、const修饰指针

生活中我们把门牌号也叫地址&#xff0c;在计算机中我们把内存单元的编号也称为地址。C语⾔中给地址起 了新的名字叫&#xff1a;指针。 所以我们可以理解为&#xff1a;内存单元的编号地址指针 1、指针变量 我们知道的是&#xff1a;数组名是数组首元素的地址。也就是说&…

中断服务程序模板

通常定时器初始化过程如下: ①对 TMOD赋值,以确定TO和T1的工作方式。 ②计算初值,并将初值写入THO、TLO或TH1、TL1。 ③中断方式时&#xff0c;则对IE赋值&#xff0c;开放中断。 ④使TRO或TR1置位&#xff0c;启动定时器/计数器定时或计数。 代码 利用定时器0工作方式1&…

轻松设置Facebook自动隐藏评论和删除评论功能

Facebook作为海外营销的最大流量平台之一&#xff0c;是很多跨境卖家争夺的市场&#xff0c;希望可以通过Facebook这个全球性的平台来推广自己的产品或服务。身处这个竞争激烈的市场&#xff0c;任何一条负面评论或不当言论出现在你的品牌页面上都可能影响到品牌形象&#xff0…

臻奶惠无人售货机:新零售时代的便捷消费革命

臻奶惠无人售货机&#xff1a;新零售时代的便捷消费革命 在新零售的浪潮中&#xff0c;智能无人售货机作为一个创新的消费模式&#xff0c;已经成为距离消费者最近的便捷购物点之一。这种模式不仅能够满足居民对消费升级的需求&#xff0c;还能通过建立多样化和多层次的消费体…

k8s练习-创建一个Deployment

创建Deployment 创建一个nginx deployment [rootk8s-master home]# cat nginx-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata:name: nginx-deployment spec:selector:matchLabels:app: nginx # 配置pod的labelsreplicas: 2 # 声明2个副本template:metada…

spring boot自动配置原理-怎样回答这个问题

首先我们说一下自动配置的概念。 自动配置&#xff1a;遵循约定大约配置的原则&#xff0c;在boot程序启动后&#xff0c;起步依赖中的一些bean对象会自动注入到ioc容器 例子 程序引入spring-boot-starter-web 起步依赖&#xff0c;启动后&#xff0c;会自动往ioc容器中注入…

记一次 pdfplumber 内存泄漏导致的服务器宕机

有一个项目需求&#xff0c;要在每天凌晨5点的时候执行一个任务&#xff0c;获取一系列的PDF文件并解析。 后端是Django框架&#xff0c;定时任务用Celery来实现的。 本地跑没什么问题&#xff0c;但是一放到服务器上跑就会宕机&#xff0c;而且是毫无征兆的宕机&#xff0c;…

黑马HTMLCSS基础

黑马的笔记和资料都是提供好了的&#xff0c;这个文档非常适合回顾复习。我在黑马提供的笔记上做了一些微不足道的补充&#xff0c;以便自己复习查阅。该笔记比较重要的部分是 表单&#xff0c;http请求 第一章. HTML 与 CSS HTML 是什么&#xff1a;即 HyperText Markup lan…

使用虚拟引擎为AR体验提供动力

Powering AR Experiences with Unreal Engine ​​​​​​​ 目录 1. 虚拟引擎概述 2. 虚拟引擎如何为AR体验提供动力 3. 虚拟引擎中AR体验的组成部分是什么&#xff1f; 4. 使用虚拟引擎创建AR体验 5. 虚拟引擎中AR的优化提示 6. 将互动性融入AR与虚拟引擎 7. 在AR中…