Redis的Java客户端
创始人
2024-02-01 16:35:35

目录

1 前言

2 Jedis客户端

2.1 jedis快速入门 

 2.2Jedis连接池

3 SpringDataRedis

3.1快速入门 

3.2ReisTemplate配置序列化工具

3.3 StringRedisTemplate 


1 前言

在Redis官网中提供了各种语言的客户端,地址:https://redis.io/resources/clients/

 

因为前三个是官方推荐学习的,而第三个又是基于分布式的,不适合基础学习,所以重点学习前两个。

又因为Java中有前两个命令的整合,叫做Spring Data Redis,但有的企业又是只用到了第一个

 所以,我们主要学习两个,Jedis和Spring Data Redis

2 Jedis客户端

2.1 jedis快速入门 

Jedis的官网地址: GitHub - redis/jedis: Redis Java client designed for performance and ease of use.,我们先来个快速入门:

温馨提示:一下代码都是在单元测试里实现的哦~

1. 创建Maven工程

2. 导入Jedis客户端h和单元测试依赖:

redis.clientsjedis3.7.0org.junit.jupiterjunit-jupiter5.7.0test

3.  开始实现Jdedis客户端操作

  • 建立连接
  • @BeforeEachpublic void setUp(){// 1.new Jedis(ip地址,端口)jedis = new Jedis("192.168.110.128",6379);//2.输入密码 authjedis.auth("123321");//3.选择库jedis.select(0);
    }
  • 编写Redis操作(String类型操作)
  • //redis操作@Testpublic void testString(){String result = jedis.set("name", "Jack");System.out.println(result);String name = jedis.get("name");System.out.println(name);}
  • 关闭资源
  •     //关闭资源@AfterEachpublic void tearDown(){//健壮性判断if (jedis != null){jedis.close();}}

最后运行结果:

 完整代码如下:

package com.itheima.test;import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;/*** @Author 华子* @Date 2022/11/19 11:15* @Version 1.0*/
public class JedisTest {private Jedis jedis;//建立连接@BeforeEachpublic void setUp(){// 1.new Jedis(ip地址,端口)jedis = new Jedis("192.168.110.128",6379);//2.输入密码 authjedis.auth("123321");//3.选择库jedis.select(0);}//redis操作@Testpublic void testString(){String result = jedis.set("name", "Jack");System.out.println(result);String name = jedis.get("name");System.out.println(name);}//关闭资源@AfterEachpublic void tearDown(){//健壮性判断if (jedis != null){jedis.close();}}}

 2.2Jedis连接池

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

连接池创建方法如下代码:

package com.itheima.jedis.util;import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisFactory;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;/*** @Author 华子* @Date 2022/11/19 11:41* @Version 1.0*/
public class JedisConnectFactory {private static final JedisPool jedisPool;static {//1.配置连接池JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();//设置最大连接池数量jedisPoolConfig.setMaxTotal(8);//设置最大空闲连接jedisPoolConfig.setMaxIdle(8);//设置最小空闲连接jedisPoolConfig.setMinIdle(0);//设置最大等待时间(当没有空闲连接时,等待的时间)jedisPoolConfig.setMaxWaitMillis(1000);//2.建立连接池(配置参数,ip地址,端口,等待时间,密码)jedisPool = new JedisPool(jedisPoolConfig,"192.168.110.128",6379,1000,"123321");}//3.提供对外调用方法public static Jedis getJedis(){return jedisPool.getResource();}
}

这样连接池就创建成功啦~

而我们Jedis快速入门的时候,建立连接就变为调用这个静态类的getJedis方法了

如图:

整体代码:

package com.itheima.test;import com.itheima.jedis.util.JedisConnectFactory;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;/*** @Author 华子* @Date 2022/11/19 11:15* @Version 1.0*/
public class JedisTest {private Jedis jedis;//建立连接@BeforeEachpublic void setUp(){// 1.new Jedis(ip地址,端口)//jedis = new Jedis("192.168.110.128",6379);jedis = JedisConnectFactory.getJedis();//2.输入密码 authjedis.auth("123321");//3.选择库jedis.select(0);}//redis操作@Testpublic void testString(){String result = jedis.set("name", "Jack");System.out.println(result);String name = jedis.get("name");System.out.println(name);}//关闭资源@AfterEachpublic void tearDown(){//健壮性判断if (jedis != null){jedis.close();}}}

这里提一嘴,关闭资源依然是jedis.close 方法,但是,底层变成了归还线程池

 

3 SpringDataRedis

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

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

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

  • 支持Redis的发布订阅模型

  • 支持Redis哨兵和Redis集群

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

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

  • 支持基于Redis的JDKCollection实现

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

3.1快速入门 

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

1.导入依赖坐标


4.0.0org.springframework.bootspring-boot-starter-parent2.5.7 com.heimaredis-demo0.0.1-SNAPSHOTredis-demoDemo project for Spring Boot1.8org.springframework.bootspring-boot-starter-data-redisorg.apache.commonscommons-pool2com.fasterxml.jackson.corejackson-databindorg.projectlomboklomboktrueorg.springframework.bootspring-boot-starter-testtestorg.springframework.bootspring-boot-maven-pluginorg.projectlomboklombok

2. 配置( redis springboot中的application.yaml文件 )

spring:redis:host: 192.168.110.128port: 6379password: 123321lettuce:pool:max-active: 8max-idle: 8min-idle: 0max-wait: 1000ms

3. 测试代码

@SpringBootTest
class RedisDemoApplicationTests {//注入RedisTemplate@Autowiredprivate RedisTemplate redisTemplate;@Testvoid testString() {// 写入一条String数据redisTemplate.opsForValue().set("name", "虎哥");// 获取string数据Object name = redisTemplate.opsForValue().get("name");System.out.println("name = " + name);}
}

3.2ReisTemplate配置序列化工具

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

其实这个就是之前写入的 name:虎哥,只不过被序列化成了这个样子。

为了方便我们的可读性,还有释放内存空间,我们要对RedisTemplate进行配置序列化方式

代码如下:

package com.itheima.redis.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;/*** @Author 华子* @Date 2022/11/19 19:47* @Version 1.0*/
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory){//1.创建RedisTemplateRedisTemplate redisTemplate = new RedisTemplate<>();//2.设置连接工厂redisTemplate.setConnectionFactory(connectionFactory);//3.创建序列化工具GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();//4.设置序列化工具//设置keyredisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setHashKeySerializer(RedisSerializer.string());//设置valueredisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);//5.返回return redisTemplate;}
}

 这样我们在重新运行,就会正常啦~

那么,问题来了,如果传入的是Java对象呢?能不能可以正常的序列化?

直接试一试:

新建一个实体类User

package com.itheima.redis.pojo;import lombok.Data;/*** @Author 华子* @Date 2022/11/19 19:57* @Version 1.0*/@Data
public class User {private String name;private Integer age;public User(String name, Integer age) {this.name = name;this.age = age;}public User() {}
}

传入User对象 

@Testvoid testObject(){User user = new User("华子",21);redisTemplate.opsForValue().set("user:100",user);User userInfo = (User) redisTemplate.opsForValue().get("user:100");System.out.println(userInfo);}

依然可以成功序列化Json对象,并且里面还有一个参数,实体类标识,这是用于读取的时候反序列化Java对象的~

3.3 StringRedisTemplate 

尽管JSON的序列化方式可以满足我们的需求,但依然存在一些问题,如图:

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

 为了减少内存的消耗,我们可以采用手动序列化的方式,换句话说,就是不借助默认的序列化器,而是我们自己来控制序列化的动作,同时,我们只采用String的序列化器,这样,在存储value时,我们就不需要在内存中就不用多存储数据,从而节约我们的内存空间

 代码就变成了如下方式(添加了手动序列化和反序列化)

package com.itheima;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.itheima.redis.pojo.User;
import net.minidev.json.JSONObject;
import net.minidev.json.JSONValue;
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;
import org.springframework.data.redis.core.StringRedisTemplate;@SpringBootTest
class StringRedisTemplateTest {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Testvoid testString() {stringRedisTemplate.opsForValue().set("name","小帅");String name = stringRedisTemplate.opsForValue().get("name");System.out.println(name);}private static final ObjectMapper mapper = new ObjectMapper();@Testvoid testSaveUser() throws JsonProcessingException {// 创建对象User user = new User("虎哥", 21);// 手动序列化String json = mapper.writeValueAsString(user);// 写入数据stringRedisTemplate.opsForValue().set("user:200", json);// 获取数据String jsonUser = stringRedisTemplate.opsForValue().get("user:200");// 手动反序列化User user1 = mapper.readValue(jsonUser, User.class);System.out.println("user1 = " + user1);}}

这样就可以不用占内存啦~ 

相关内容

热门资讯

应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...