Redis5:Redis的Java客户端——Jedis与SpringDataRedis详解

目录

1、Jedis客户端

1.1使用过程

2、SpringDataRedis

2.1 SpingDataRedis介绍

2.2SpringDataRedis快速入门

2.3RedisTemplate的RedisSerializer

2.3.1RedisTemplate中JDK序列化局限性

2.3.2方式一:改变RedisTemplate的序列化方式

2.3.3RedisTemplate存储一个对象

2.3.4 方式二:StringRedisTemplate


1、Jedis客户端

1.1使用过程

1、新建一个maven项目

2、引入依赖

<!--jedis-->
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.7.0</version>
</dependency><!--单元测试-->
<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>RELEASE</version><scope>test</scope>
</dependency>

3、建立连接

@BeforeEach
void setUp(){//1、建立连接jedis = new Jedis("120.53.240.101",6379);//2、设置密码jedis.auth("123321");//3、选择库jedis.select(5);
}

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

package com.tang.util;import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;public class JedisConnectionFactory {// Jedis连接池对象private static JedisPool jedisPool;static {//配置连接池JedisPoolConfig jedisPoolConfig  = new JedisPoolConfig();//  最大连接数jedisPoolConfig.setMaxTotal(8);// 最大空闲连接数,最多可创建的连接jedisPoolConfig.setMaxIdle(8);// 最小空闲连接数,最少可创建的连接数,长时间没链接时就销毁至0,当然也可以预备一些连接jedisPoolConfig.setMinIdle(0);//默认值是-1,表示没有限制// 设置最长等待时间(ms),连接池里没有连接时就等待,超过这个时间就抛异常jedisPoolConfig.setMaxWaitMillis(1000);//创建连接池对象,1000是连接超时时间jedisPool = new JedisPool(jedisPoolConfig,"120.53.240.101", 6379, 1000, "123321");}// 获取Jedis实例public static Jedis getJedis() {return jedisPool.getResource();}}

在测试类中,连接直接从工具类里拿

@BeforeEach
void setUp(){//1、建立连接jedis = JedisConnectionFactory.getJedis();//2、选择库jedis.select(6);
}

4、测试string

set类型

@Test
void testString(){ //存入数据String result = jedis.set("name","tang");System.out.println("result="+result);//获取数据String name = jedis.get("name");System.out.println("name="+name);
}

Hash类型

@Test
void testHash(){jedis.hset("user","name","tang");jedis.hset("user","age","22");Map<String, String> user = jedis.hgetAll("user");System.out.println(user);
}

5、释放资源

@AfterEach
void tearDown(){//健壮性判断,关闭链接if(jedis != null){jedis.close();}
}

6、结果返回

string

hash

2、SpringDataRedis

2.1 SpingDataRedis介绍

SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,

官网Spring Data Redis

  • 提供了对不同Redis客户端的整合(Lettuce和jedis)

  • 提供了RedisTemplate统一API来操作Redis

  • 支持Redis的发布订阅模型

  • 支持Redis哨兵和Redis集群

  • 支持基于Lettuce的响应式编程

  • 支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化

2.2SpringDataRedis快速入门

        SPringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中:

SpringBoot已经提供了对SpringDataRedis的支持,使用非常简单:

新建项目,我们在这创建一个SpringBoot项目

可以提前勾选几个依赖。(注意!!在我这,这个SpringBoot版本进去要改一下,不然会因为版本过高等问题出错

1、导入依赖

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

2、配置文件

spring:redis:host: 120.53.240.101port: 6379password: 123321lettuce:pool:max-active: 8  #最大连接max-idle: 8 #最大空闲连接min-idle: 0 #最小空闲连接max-wait: 100 #最大等待时间

3、注入RedisTemplate

@Autowired
private RedisTemplate redisTemplate;

4、编写测试

在这里我们看到,set()并没有强硬要求我们必须传入字符串参数

@Test
void testString() {//写入一条String类型数据redisTemplate.opsForValue().set("name","tang");//读取一条String类型数据Object name = redisTemplate.opsForValue().get("name");System.out.println("name="+name);
}

2.3RedisTemplate的RedisSerializer

2.3.1RedisTemplate中JDK序列化局限性

当我们尝试用SpringDataRdies修改某个键的值时,会发现如下情景:

我们先在数据库中存入键name,并把他的value设为Jack

然后我们调用SpringDataRedis,将键name的value设置为tang

得到如下返回结果

回到我们的redis命令行去get name,

我们会发现name的值并未改变

获取一下全部的keys,出现一串不知名的key。

我们来get一下这个key,返回的还是一串字符

为什么会这样子?

        我们看set方法我们发现他接受的并不是字符串,它可以接收任何类型的对象,然后转换成redis可以处理的字节(JDK的序列化工具ObjectOutputStream)再写入redis。

debug进入set方法,我们发现它最终进入到了JdkSerializer

最后调用ObjectOutputStream

这样写有什么问题?

  • 可读性差

  • 内存占用较大

  • 容易出现bug:不是修改,因为key也被序列化

2.3.2方式一:改变RedisTemplate的序列化方式

crtl+H查看RedisSerializer的subTypes

JdkSerializationRedisSerializer我们已经发现它并不好用。

StringRedisSerializer是专门处理字符串的序列化工具getbytes:当key或者hashkey是字符串类型的时候可以使用。

GenericJackson2JsonRedisSerializer这是一个转JSON字符串的序列化工具:适合于value使用

我们手写一个工具类,自定义RedisTemplate的序列化方式

package com.tang.springdataredisdemo.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;
import sun.net.www.content.text.Generic;/*** 注册一个配置类,实现自定义Redis序列化* @author tang* @date 2021-06-07 16:05* @desc*/
@Configuration
public class RedisConfig {@Bean// 自定义Redis序列化public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {//创建RedisTemplate对象RedisTemplate<String, Object> template = new RedisTemplate<>();//设置连接工厂template.setConnectionFactory(connectionFactory);//创建JSON的序列化工具GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();//设置key序列化方式template.setKeySerializer(RedisSerializer.string());template.setHashKeySerializer(RedisSerializer.string());//设置value序列化方式template.setValueSerializer(jsonRedisSerializer);template.setHashValueSerializer(jsonRedisSerializer);//返回RedisTemplate对象return template;}
}

添加这个配置类后,我们对测试的部分进行一些修改,改为泛型格式

@Autowired
private RedisTemplate<String,Object> redisTemplate;

还需要添加一个依赖

<!--Jackson依赖-->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId>
</dependency>

idea里结果返回如下:

现在去redis数据库里看一下,没问题了!

2.3.3RedisTemplate存储一个对象

创建一个User类

package com.tang.springdataredisdemo.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {private String name;private Integer age;
}

编写测试案例

@Test
void testObject() {User user = new User("tang", 18);//写入一条Object类型数据redisTemplate.opsForValue().set("user:100",user);//读取一条Object类型数据(直接强转)User user1 =(User) redisTemplate.opsForValue().get("user:100");System.out.println("user="+user1);
}

结果返回如下

在数据库中,自动转化为JSON风格的数据存储起来

图片上的JSON中还有一个“@class”,这个字段帮助将json格式反序列化为对应的对象(反射

但这会带来额外的内存开销

2.3.4 方式二:StringRedisTemplate

在2.3.3中我们发现使用GenericJackson2JsonRedisSerializer会产生额外的字段,消耗了很大一部分的内存空间。

为了节省内存空间,我们并不会使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化

Spring默认提供了一个StringRedisTemplate类,他的key和value的序列化方式默认就是String方式。省去了我们自定义的时间。

在测试类注入

@Autowired
private StringRedisTemplate  stringRedisTemplate;

修改测试用例,在存入对象的部分多了一个手动序列化和反序列化的过程

@Test
void testString() {//写入一条String类型数据stringRedisTemplate.opsForValue().set("name","tang");//读取一条String类型数据Object name = stringRedisTemplate.opsForValue().get("name");System.out.println("name="+name);
}
@Test
void testHash(){stringRedisTemplate.opsForHash().put("user:200","name","tang");stringRedisTemplate.opsForHash().put("user:200","age","18");Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("user:200");System.out.println("entries="+entries);}
//序列化工具,使用fastjson也是可以的
private static final ObjectMapper objectMapper = new ObjectMapper();@Test
void testObject() throws JsonProcessingException {//创建对象User user = new User("tang", 18);//手动序列化String json = objectMapper.writeValueAsString(user);//写入一条Object类型数据stringRedisTemplate.opsForValue().set("user:100",json);//读取一条Object类型数据(直接强转)String jsonUser =stringRedisTemplate.opsForValue().get("user:100");//手动反序列化objectMapper.readValue(jsonUser,User.class);System.out.println("user="+jsonUser);
}

结果显示

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

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

相关文章

零基础 “入坑” Java--- 十三、再谈类和接口

文章目录一、Object类1.获取对象信息2.对象比较&#xff1a;equals方法二、再谈接口1.比较相关接口2.Cloneable接口和深拷贝三、内部类1.匿名内部类2.实例内部类3.静态内部类4.局部内部类在之前的学习中&#xff0c;我们已经了解了有关类以及接口的知识&#xff0c;在本章节中&…

Spring Boot 一个注解搞定「加密 + 解密 + 签名 + 验签」

Spring Boot 一个注解搞定「加密 解密 签名 验签」本文基于 Spring Boot 3.x&#xff0c;通过一个自定义注解 AOP&#xff0c;一行注解即可给任何 Controller 方法加上 请求解密 → 验签 → 响应加密 → 加签 的完整链路&#xff0c;并可直接拷贝到生产环境使用。一、最终效…

《计算机网络》实验报告二 IP协议分析

目 录 1、实验目的 2、实验环境 3、实验内容 3.1 tcpdump 基本用法 3.2 wireshark基本用法 3.3 利用tcpdump抓包&#xff0c;wireshark分析包 4、实验结果与分析 4.1 tcpdump命令的基本用法 4.2 wireshark的基本用法 4.3 利用tcpdump抓包&#xff0c;wireshark分析包…

k8s学习记录(三):Pod基础-Node选择

一、前言 在上一篇文章中我们学习了Pod的一些基本的知识&#xff0c;今天我们将继续学习Pod。 二、K8S如何选择节点来运行Pod 我们知道在一个K8S集群中&#xff0c;会有多个工作节点&#xff08;Worker Node&#xff09;&#xff0c;那么k8s会选择那个node呢&#xff1f;接下…

3天功能开发→3小时:通义灵码2.0+DEEPSEEK实测报告,单元测试生成准确率92%的秘密

活动链接&#xff1a;https://developer.aliyun.com/topic/lingma-aideveloper?spma2c6h.29979852.J_9593490300.2.49b8110eeymlF8 前言 随着人工智能技术的迅猛发展&#xff0c;AI 赋能编程成为了必然趋势。通义灵码应运而生&#xff0c;它是阿里巴巴集团在人工智能与编程领…

【小沐学GIS】基于Rust绘制三维数字地球Earth(Rust、OpenGL、GIS)

&#x1f37a;三维数字地球GIS系列相关文章如下&#x1f37a;&#xff1a;1【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;OpenGL、glfw、glut&#xff09;第一期2【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;OpenGL、glfw、glut&#xff09;第二期3【小沐学GI…

ARM 学习笔记(三)

参考文献&#xff1a;《ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition》《ARM Cortex-A (ARMv7-A) Series Programmer’s Guide》1、内存类型 ARMv7-A 处理器中&#xff0c;将 Memory 定义为几种类型&#xff08;Memory Type&#xff09;&#xff1a; Strong…

Flask 框架(一):核心特性与基础配置

目录 一、为什么选择 Flask&#xff1f; 二、Flask 核心概念与初始化 2.1 程序实例初始化 2.2 运行配置&#xff1a;app.run () 参数详解 2.3 应用配置&#xff1a;三种参数设置方式 1. 字典直接配置&#xff08;简单临时场景&#xff09; 2. 配置文件导入&#xff08;生…

社交圈子系统开源社交源码 / 小程序+H5+APP 多端互通的底层技术分析

伴随社交产品向“圈子化”、“内容驱动”发展方向演进&#xff0c;打造一套支持小程序、H5、APP 互通的社交圈子系统&#xff0c;已经成为构建垂直社区的基础架构能力要求。本文围绕一套典型的多端社交兴趣平台&#xff08;即友猫社区平台&#xff09;的设计实践&#xff0c;对…

gitlab-runner配置问题记录

引言 笔者曾通过2种方式部署过 gitlab-runner&#xff0c;在 gitlab 中使用这个 runner 拉起 ci job 的过程中或多或少遇到些问题&#xff0c;主要都是 job 中无法访问宿主机的docker 等组件。本篇文档主要记录 gitlab-runner 安装及相关配置。 二进制部署 gitlab-runner 部署 …

每日面试题10:令牌桶

令牌桶算法&#xff1a;优雅的流量控制艺术在现代分布式系统中&#xff0c;流量控制如同交通信号灯般重要——它既不能让请求"堵死"系统&#xff0c;也不能放任流量"横冲直撞"。令牌桶算法&#xff08;Token Bucket Algorithm&#xff09;正是这样一种精妙…

【java】消息推送

文章目录Java网页消息推送解决方案 短轮询、长轮询、SSE、Websocket

STM32 | 有源蜂鸣器响,无源蜂鸣器播音乐

目录 Overview 有源蜂鸣器 无源蜂鸣器 有源蜂鸣器控制 GPIO配置 控制程序 无源蜂鸣器控制 反转GPIO控制 GPIO配置 控制接口 PWM控制 GPIO配置 控制函数 改变频率播音乐 原理 1. 频率决定音调 2. 占空比决定音量 GPIO初始化 结构体定义和音符频率表 播放接口 …

第十四章 gin基础

文章目录Gin快速搭建一个web服务Gin数据交互JSON串内容规范Gin使用结构体返回数据给前端Gin配置POST类型的路由Gin获取GET请求参数Gin获取POST请求参数-form-data类型Gin获取POST请求参数-JSON类型Gin获取参数绑定至结构体Gin快速搭建一个web服务 下载包 \\新建一个文件&…

Baumer工业相机堡盟工业相机如何通过YoloV8的深度学习模型实现PCB的缺陷检测(C#代码,UI界面版)

Baumer工业相机堡盟工业相机如何通过YoloV8的深度学习模型实现PCB的缺陷检测&#xff08;C#代码&#xff0c;UI界面版&#xff09;工业相机使用YoloV8模型实现PCB的缺陷检测工业相机实现YoloV8模型实现PCB的缺陷检测的技术背景在相机SDK中获取图像转换图像的代码分析工业相机图…

【Vivado那些事儿】AMD-XILINX 7系列比特流加密

前提&#xff1a;加密有风险&#xff0c;操作需谨慎前言在许多项目中&#xff0c;经过漫长的等待&#xff0c;我们的 FPGA 设计终于可以投入现场部署了。前期的资金的投入及知识产权的保护&#xff0c;我们需要对现场部署的 FPGA 进行比特流保护以防止逆向工程和未经授权的重复…

RK3588 安卓adb操作

adb&#xff08;Android Debug Bridge&#xff09;是一个用于与安卓设备进行通信和控制的工具。adb可以通过USB或无线网络连接安卓设备&#xff0c;执行各种命令&#xff0c;如安装和卸载应用&#xff0c;传输文件&#xff0c;查看日志&#xff0c;运行shell命令等。adb是安卓开…

【华为机试】70. 爬楼梯

文章目录70. 爬楼梯描述示例 1示例 2提示解题思路核心分析问题建模算法实现方法1&#xff1a;动态规划&#xff08;标准解法&#xff09;方法2&#xff1a;空间优化动态规划&#xff08;最优解&#xff09;方法3&#xff1a;递归 记忆化方法4&#xff1a;数学公式&#xff08;…

山东大学软件学院面向对象期末复习

面向对象 文章目录面向对象04 类封装接口 抽象类05 消息&#xff0c;实例化&#xff0c;静态变量方法消息动/静态类型语言对象创建类及实例具有下面特征对象数组的创建静态数据成员构造函数06_0 继承继承是向下传递的JAVA为什么不支持多重继承继承的形式特殊化继承替换原则规范…

让 Windows 用上 macOS 的系统下载与保姆级使用教程

模拟苹果桌面软件下载&#xff1a;https://xpan.com.cn/s/8NFAGT 还记得 Windows 11刚发布时&#xff0c;很多人就说“果里果气"的&#xff0c;但界面确实做的漂亮。 不知道现在有多少小伙伴正用着macOS&#xff0c;不过我敢确定&#xff0c;喜欢macOS的人绝对不少&#…