Redis
的Java
客户端
前面已经提到了Redis
的常用的五种数据结构,并且通过命令行的方式进行了操作,但是在日常使用Redis
时,大部分情况下都是基于编码
的方式完成的。Redis
的官网(https://redis.io/clients
)提供了各种语言的客户端:
Redis
对于Java
语言的支持也十分到位,其提供了很多Java
语言的客户端:
Jedis
简介
Jedis
是一个十分经典的RedisJava客户端
,其以Redis
的命令作为方法名称,学习成本较低(会用Redis
就能使用Jedis
),简单实用,但是Jedis
实例是线程不安全的,多线程环境下需要和连接池配合使用。
Lettuce
简介
Lettuce
是基于Netty
实现的,支持同步、异步和响应式编程的方式,并且线程是安全的,可以完美支持Redis
的哨兵模式、集群模式和管道模式。
Redisson
简介
Redisson
是基于Redis
实现的分布式、可伸缩的Java
数据结构集合。包含了诸如Map
、Queue
、Lock
、Semaphore
、AtomicLong
等强大功能。
SpringDataRedis
简介
SpringDataReids
是Jedis
和Lettuce
的结合体:它在两者基础上提供了统一的操作模板(如RedisTemplate
)、序列化支持、事务管理及Spring生态集成,既保留了Jedis
的简洁性和Lettuce
的高并发性能,又通过抽象层简化了Redis
的复杂操作,是开发比较推荐的RedisJava客户端
。
Jedis
快速入门
Jedis
的快速入门十分简单,主要分为三步(以Maven
为例):1.引入依赖、2.建立Redis
连接、3.进行Redis
操作,接下来就根据这三步进行讲解:
1.引入依赖
由于使用了Maven
作为构建工具,引入Jedis
的依赖相当的简单,我们只需要在pom.xml
文件中引入Jedis
的Maven
坐标即可:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>5.2.0</version>
</dependency>
上述代码只是我的版本选择,不一定需要这么高版本的Jedis
依赖,根据自己的需求选择即可。
2.建立连接
由于在使用Jedis
操作Redis
之前,都必须建立和Redis
的连接,所以说我们可以将建立Redis
连接的代码封装成一个方法,在每次操作之前调用即可:
@BeforeEach
void setUp() {
// 建立连接
jedis = new Jedis("192.168.181.134", 6379);
// 设置密码
jedis.auth("your password");
// 选择库
jedis.select(0);
}
在测试
时,可以使用@BeforeEach注解
,自动在每一个测试方法执行前,先执行setUp
方法和Redis
建立连接。可以直接通过new
直接初始化一个Jedis
对象,需要传入的参数是Redis主机地址和端口号
,如果Redis
设置了密码,那么需要通过auth
方法进行验证,这和命令行是一样的。
3.Redis
操作
当连接建立好之后,就可以通过Jedis
中的方法,通过Java
代码操作Redis
了,Jedis
有一个好处就是方法名是以Redis
中的命令命名的,所以说操作起来就会十分简单:
void testString() {
// 存入数据
String result = jedis.set("username", "jack");
System.out.println(result);
// 获取数据
String username = jedis.get("username");
System.out.println(username);
}
通过set
方法向Redis
中存入了一条String
类型的数据,其Value
是jack
,其Key
是username
;并且通过get
方法,我们也能通过Key
取得对应的Value
。
建立了与Redis
的连接之后,完成了对应的操作就需要进行资源释放,关闭和Redis
的连接:
@AfterEach
void close() {
jedis.close();
}
Jedis
连接池
上文提到Jedis
本身的线程是不安全的,并且在频繁的创建和销毁连接的时候会有性能损耗,所以说建议使用Jedis
连接池替代本身Jedis
直连的方式。其中Jedis
连接池和关系型数据库连接池
需要配置的选项差不多,主要需要配置的是:最大连接数
、最大空闲连接数
、最长等待时间等
……,并且,我们可以将连接池配置的代码封装为一个工具类
,之后就可以直接从这个工具类中获取Jedis
的连接了:
package com.wzb.util;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisConnectionFactory {
private static final JedisPool jedisPool;
static {
// 配置连接池
JedisPoolConfig poolConfig = new JedisPoolConfig();
// 设置连接池最大连接数
poolConfig.setMaxTotal(8);
// 设置连接池最大空闲连接数
poolConfig.setMaxIdle(8);
// 设置连接池最小空闲连接数
poolConfig.setMaxIdle(4);
// 设置连接池最大等待时间
poolConfig.setMaxWaitMillis(1000);
// 创建连接池对象
jedisPool = new JedisPool(poolConfig, "192.168.181.134", 6379,
1000, "your password");
// 连接池对象初始化需要连接池配置类、Redis主机、端口、超时时间(ms),密码
}
public static Jedis getConnection() {
return jedisPool.getResource();
}
}
Jedis
本身自带了JedisPool
连接池,所以说我们可以直接在类中对JedisPool
进行配置,从而完成Jedis
连接池的配置。并且我们在工具类中封装了static方法
来获取Jedis
连接,这个方法是调用的JedisPool
中的getResource
方法获取Jedis
连接的,这个方法会从连接池中返回一个Jedis
连接:
有了连接池之后,我们就可以修改原来的setUp
方法,将直接new Jedis
连接改为工具类中的getConnection
方法,从连接池中获取连接:
@BeforeEach
void setUp() {
// 建立连接
jedis = JedisConnectionFactory.getConnection();
// 选择库
jedis.select(0);
}
但是在释放资源的时候,可以直接使用Jedis
中的close
方法,因为这个方法会先检查是否有连接池,如果有连接池,就不会直接销毁连接,而是将连接归还连接池: