Redis中的Java客户端

news2024/11/25 14:42:40

一、Jedis

Jedis是一个Java实现的Redis客户端连接工具。

Jedis使用非常简单,直接引入依赖。基于默认参数的Jedis连接池,初始化连接池类(使用默认连接池参数)JedisPool,获取一个Jedis连接Jedis jedis=jp.getResource()。

Jedis是线程不安全的,多线程使用同一个Jedis实例,会出现并发问题,原因是底层共用了一个输入输出流

1.1  Jedis快速入门

Jedis的官网地址: GitHub - redis/jedis: Redis Java client,我们先来个快速入门:

① 新建一个Maven工程并引入以下依赖  

<!--引入Jedis依赖-->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.2.0</version>
</dependency>

<!--引入单元测试依赖-->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.8.2</version>
    <scope>test</scope>
</dependency>

② 编写测试类并与Redis建立连接

private Jedis jedis;

@BeforeEach //被该注解修饰的方法每次执行其他方法前自动执行
void setUp(){
    // 1. 获取连接
    jedis = new Jedis("192.168.230.88",6379);
    // 2. 设置密码
    jedis.auth("132537");
    // 3. 选择库(默认是下标为0的库)
    jedis.select(0);
}

③ 编写一个操作数据的方法(这里以操作String类型为例)

@Test
public void testString(){
    // 1.往redis中存放一条String类型的数据并获取返回结果
    String result = jedis.set("url", "https://www.oz6.cn");
    System.out.println("result = " + result);

    // 2.从redis中获取一条数据
    String url = jedis.get("url");
    System.out.println("url = " + url);
}

④ 最后不要忘记编写一个释放资源的方法

    @AfterEach //被该注解修饰的方法会在每次执行其他方法后执行
    void tearDown(){
        // 1.释放资源
        if (jedis != null){
            jedis.close();
        }
    }

⑤ 执行testString()方法后测试结果如图所示

1.2  Jedis连接池

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

public class JedisConnectionFactory {
    private static final JedisPool jedisPool;

    static {
        //配置连接池
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(8);
        jedisPoolConfig.setMaxIdle(8);
        jedisPoolConfig.setMinIdle(0);
        jedisPoolConfig.setMaxWaitMillis(200);
        //创建连接池对象
        jedisPool = new JedisPool(jedisPoolConfig,"192.168.230.88",6379,1000,"132537");
    }

    public static Jedis getJedis(){
       return jedisPool.getResource();
    }
}

二、SpringDataRedis介绍

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

官网地址:Spring Data Redis

  • 提供了对不同Redis客户端的整合(LettuceJedis

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

  • 支持Redis的发布订阅模型

  • 支持Redis哨兵和Redis集群

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

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

  • 支持基于Redis的JDKCollection实现

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

三、SpringDataRedis快速入门

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

① 首先新建一个Spring Boot工程

② 然后引入连接池依赖

<!--连接池依赖-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

③ 编写配置文件application.yml(连接池的配置在实际开发中是根据需求来的)

spring:
  redis:
    host: 192.168.230.88 #指定redis所在的host
    port: 6379  #指定redis的端口
    password: 132537  #设置redis密码
    lettuce:
      pool:
        max-active: 8 #最大连接数
        max-idle: 8 #最大空闲数
        min-idle: 0 #最小空闲数
        max-wait: 100ms #连接等待时间

④ 编写测试类执行测试方法

@SpringBootTest
class RedisDemoApplicationTests {

	@Resource
	private RedisTemplate redisTemplate;

	@Test
	void testString() {
		// 1.通过RedisTemplate获取操作String类型的ValueOperations对象
		ValueOperations ops = redisTemplate.opsForValue();
		// 2.插入一条数据
		ops.set("blogName","Vz-Blog");
		
		// 3.获取数据
		String blogName = (String) ops.get("blogName");
		System.out.println("blogName = " + blogName);
	}
}

四、RedisSerializer配置

RedisTemplate可以接收任意Object作为值写入Redis,只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化,得到的结果是这样的

缺点:

  • 可读性差

  • 内存占用较大

那么如何解决以上的问题呢?我们可以通过自定义RedisTemplate序列化的方式来解决。

编写一个配置类RedisConfig :

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
        // 1.创建RedisTemplate对象
        RedisTemplate<String ,Object> redisTemplate = new RedisTemplate<>();
        // 2.设置连接工厂
        redisTemplate.setConnectionFactory(factory);

        // 3.创建序列化对象
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();

        // 4.设置key和hashKey采用String的序列化方式
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);

        // 5.设置value和hashValue采用json的序列化方式
        redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);

        return redisTemplate;
    }
}

此时我们已经将RedisTemplate的key设置为String序列化,value设置为Json序列化的方式,再来执行方法测试

由于我们设置的value序列化方式是Json的,因此我们可以直接向redis中插入一个对象

@Test
void testSaveUser() {
    redisTemplate.opsForValue().set("user:100", new User("Vz", 21));
    User user = (User) redisTemplate.opsForValue().get("user:100");
    System.out.println("User = " + user);
}

尽管Json序列化可以满足我们的需求,但是依旧存在一些问题。

如上图所示,为了在反序列化时知道对象的类型,JSON序列化器会将类的class类型写入json结果中,存入Redis,会带来额外的内存开销。

那么我们如何解决这个问题呢?我们可以通过下文的StringRedisTemplate来解决这个问题。

五、StringRedisTemplate

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

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

我们可以直接编写一个测试类使用StringRedisTemplate来执行以下方法:

@SpringBootTest
class RedisStringTemplateTest {

	@Resource
	private StringRedisTemplate stringRedisTemplate;

	@Test
	void testSaveUser() throws JsonProcessingException {
		// 1.创建一个Json序列化对象
		ObjectMapper objectMapper = new ObjectMapper();
		// 2.将要存入的对象通过Json序列化对象转换为字符串
		String userJson1 = objectMapper.writeValueAsString(new User("Vz", 21));
		// 3.通过StringRedisTemplate将数据存入redis
		stringRedisTemplate.opsForValue().set("user:100",userJson1);
		// 4.通过key取出value
		String userJson2 = stringRedisTemplate.opsForValue().get("user:100");
		// 5.由于取出的值是String类型的Json字符串,因此我们需要通过Json序列化对象来转换为java对象
		User user = objectMapper.readValue(userJson2, User.class);
		// 6.打印结果
		System.out.println("user = " + user);
	}

}

执行完毕回到Redis的图形化客户端查看结果

六、总结

RedisTemplate的两种序列化实践方案,两种方案各有各的优缺点,可以根据实际情况选择使用。

方案一:

  1. 自定义RedisTemplate

  2. 修改RedisTemplate的序列化器为GenericJackson2JsonRedisSerializer

方案二:

  1. 使用StringRedisTemplate

  2. 写入Redis时,手动把对象序列化为JSON

  3. 读取Redis时,手动把读取到的JSON反序列化为对象

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

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

相关文章

Git将某个文件合并到指定分支

企业开发中&#xff0c;经常会单独拉分支去做自己的需求开发&#xff0c;但是某些时候一些公共的配置我们需要从主线pull&#xff0c;这时候整个分支merge显然不合适 1.切换至待合并文件的分支 git checkout <branch>2.将目标分支的单个文件合并到当前分支 git checkou…

线上党建展厅有哪些功能,如何搭建一个成功的线上党建展厅

引言&#xff1a; 随着互联网的飞速发展&#xff0c;线上党建展厅成为党建宣传的新平工具&#xff0c;它提供了一个方便的党建学习、交流和展示的空间。那么线上党建展厅有哪些功能&#xff0c;如何搭建一个成功的线上党建展厅呢&#xff1f; 一、线上党建展厅有哪些功能 1.组…

SSH 隧道是什么,有什么用

本地主机&#xff08;A&#xff09;&#xff1a;需要访问目标服务器的主机。 跳板服务器&#xff08;B&#xff09;&#xff1a;位于本地主机和目标服务器之间的第三方服务器。跳板服务器上已经配置好SSH服务&#xff0c;并允许SSH隧道传输。 目标服务器&#xff08;C&#xff…

vscode调试debug,launch.json文件‘args’无法发传递给脚本

问题&#xff1a;调试时&#xff0c;脚本执行&#xff0c;发现在launch.json文件中明明定义了“args”参数&#xff0c;却没有传递给执行命令。 解决&#xff1a; launch.json中的"name"参数不要随便起&#xff0c;要与执行的文件名一致&#xff01; 参考链接&…

RT-Thread Studio学习(十三)DAC

RT-Thread Studio学习&#xff08;十三&#xff09;DAC 一、简介二、新建RT-Thread项目并使用外部时钟三、启用DAC四、测试五、总结 一、简介 本文将基于STM32F407VET芯片介绍如何在RT-Thread Studio开发环境下使用DAC设备。硬件及开发环境如下&#xff1a; OS WIN10STM32F40…

聆听人生故事:欧美用户与“爱可声”助听器的相伴时刻

在日常生活中&#xff0c;听力下降是一种常见的问题&#xff0c;尤其在年长者中更为普遍。随着人口老龄化的加剧&#xff0c;助听器市场也在不断扩大。据世界卫生组织发布的《世界听力报告》显示&#xff0c;目前全球五分之一的人听力受损&#xff0c;听力损失影响全球超过15亿…

pxe高效批量网络装机 以及安装教程

系统装机的三种引导模式 1.pe 2光驱 3.网卡 打开本机桌面 可以看见背景图片 查看配置文件内容 文件时引导选项的功能 pxe原理&#xff1a; 先根据dhcp找到IP地址、和引导程序的地址&#xff0c;还提供客户机tftp地址&#xff0c;因为tftp是小文件&#xff0c;容量小&#…

龙芯3A6000_统信UOS上使用UDOM工具箱

原文链接&#xff1a;龙芯3A6000|统信UOS上使用UDOM工具箱 大家好&#xff01;今天&#xff0c;我非常兴奋地和大家分享一篇关于在龙芯3A6000搭载统信UOS系统上使用UDOM工具箱的实用指南。这不仅是一次技术探索&#xff0c;也是一次提升运维效率的旅程。 首先&#xff0c;让我们…

【NPL】自然语言处理(Natural Language Processing,NLP)的发展简述

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读文章&#xff01; 此篇是【话题达人】序列文章&#xff0c;这一次的话题是《自然语言处理的发展》 文章将以博主的角度进行讲述&#xff0c;理解和水平有限&#xff0c;不足之处&#xff0c;望指正。 目录 背景发展线路研发关…

d2l包安装教程

目录 一、下载d2l包 1、错误的安装方法 2、正确的安装方法 二、可能会遇到的问题 1、网络超时导致下载中断 2、windows powershell激活虚拟环境时报错 一、下载d2l包 直接按照教程安装 — 动手学深度学习 2.0.0 documentation运行命令pip install d2l0.17.6安装会比较慢&…

Jira 宣布Data Center版涨价5%-15%,6年内第8次提价

近日&#xff0c;Atlassian官方面向合作伙伴发布2024年涨价通知&#xff1a; 自2024年2月15日起&#xff0c;旗下核心产品Jira Software、Confluence、Jira Service Management的DC版本&#xff08;Data Center版本&#xff09;价格提高5%-15%&#xff08;涨幅与坐席数阶梯相关…

关于C#中的async/await的理解

1. 使用async标记的方法被认为是一个异步方法&#xff0c;如果不使用await关键字&#xff0c;调用跟普通方法没有区别 static async Task Main(string[] args){Console.WriteLine("主线程id&#xff1a;" Thread.CurrentThread.ManagedThreadId);TestAwait();Consol…

数字身份所有权:Web3时代用户数据的掌控权

随着Web3时代的来临&#xff0c;数字身份的概念正焕发出崭新的光芒。在这个数字化的时代&#xff0c;用户的个人数据变得愈加珍贵&#xff0c;而Web3则为用户带来了数字身份所有权的概念&#xff0c;重新定义了用户与个人数据之间的关系。本文将深入探讨Web3时代用户数据的掌控…

1127: 矩阵乘积

题目描述 计算两个矩阵A和B的乘积。 输入 第一行三个正整数m、p和n&#xff0c;0<m,n,p<10&#xff0c;表示矩阵A是m行p列&#xff0c;矩阵B是p行n列&#xff1b; 接下来的m行是矩阵A的内容&#xff0c;每行p个整数&#xff0c;用空格隔开&#xff1b; 最后的p行是矩…

C++大学教程(第九版)5.15修改GradeBook

目录 题目 代码 运行命令&#xff08;在控制台输入&#xff09; 运行截图 题目 &#xff08;修改GradeBook&#xff09;修改图5.9~图5.11所示的 GradeBook 程序&#xff0c;使它计算一组成绩的平均成绩。 成绩A为4分&#xff0c;成绩B为3分&#xff0c;依次类推。 A:4 B:3…

UML-通信图和交互概览图(通信图和顺序图的区别与联系)

UML-通信图和交互概览图&#xff08;通信图和顺序图的区别与联系&#xff09; 一、通信图简介1.消息2.链接 二、通信图和[顺序图](https://blog.csdn.net/weixin_65032328/article/details/135587782)的联系与区别三、交互概览图四、顺序图转化为通信图练习 一、通信图简介 通…

Docker部署Flask项目

Docker部署Flask项目 一、准备项目代码二、编写Dockerfile三、服务器部署 一、准备项目代码 这里写了一个简单的Flask的demo&#xff0c;源代码如下&#xff1a; from flask import Flaskapp Flask(__name__)app.route("/") def index():return "<h1 styl…

软件测试面试200问(含答案)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、B/S架构和C/S架构区别 B/S 只需要有操作系统和浏览器就行&a…

线程、线程创建、多线程、线程同步

程序&#xff1a;为完成特定任务&#xff0c;使用计算机语言编写的一系列指令集合&#xff0c;即静态代码。 进程&#xff1a;正在执行的程序&#xff0c;操作系统分配资源的最小单位。 线程&#xff1a;进程内部最小执行单位。&#xff08;具体要做的一件事情&#xff09; …

CAN FD数据脱机记录仪的在汽车应用上的优势

CAN FD数据脱机记录仪的优势 大容量存储&#xff1a;CAN FD数据脱机记录仪通常具备大容量的存储空间&#xff0c;可以记录长时间的CAN数据。这使得它非常适合于需要长时间记录CAN数据的场景&#xff0c;例如车辆测试、故障诊断等。 离线处理&#xff1a;CAN FD数据脱机记录仪…