Java操作Redis—Jedis

之所以使用 Jedis,是因为它操作 redis 时使用的方法名与 redis 命令一致。

一、简单使用

1.1、新建 maven 项目

新建一个 maven 项目,项目结构如下:

1.2、导入依赖

<dependencies>
    <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.9.0</version>
    </dependency>
<span class="hljs-comment">&lt;!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.projectlombok<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>lombok<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.18.12<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">scope</span>&gt;</span>provided<span class="hljs-tag">&lt;/<span class="hljs-name">scope</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>

<span class="hljs-comment">&lt;!-- https://mvnrepository.com/artifact/junit/junit --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>junit<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>junit<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>4.12<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">scope</span>&gt;</span>test<span class="hljs-tag">&lt;/<span class="hljs-name">scope</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>

</dependencies>

1.3、简单测试

public class Demo {
<span class="hljs-meta">@Test</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">set</span><span class="hljs-params">()</span> {
    <span class="hljs-comment">// 开启连接</span>
    <span class="hljs-type">Jedis</span> <span class="hljs-variable">jedis</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Jedis</span>(<span class="hljs-string">"127.0.0.1"</span>, <span class="hljs-number">6379</span>);
    <span class="hljs-comment">// 执行操作</span>
    jedis.set(<span class="hljs-string">"name"</span>, <span class="hljs-string">"李四"</span>);
    <span class="hljs-comment">// 关闭连接</span>
    jedis.close();
}

<span class="hljs-meta">@Test</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">get</span><span class="hljs-params">()</span> {
    <span class="hljs-type">Jedis</span> <span class="hljs-variable">jedis</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Jedis</span>(<span class="hljs-string">"127.0.0.1"</span>, <span class="hljs-number">6379</span>);
    <span class="hljs-type">String</span> <span class="hljs-variable">name</span> <span class="hljs-operator">=</span> jedis.get(<span class="hljs-string">"name"</span>);
    System.out.println(name);
    jedis.close();
}

}

程序运行结果过:

使用 RDM 查看:

2、存储对象

想将一个对象存储到 redis 中,需要先将其转化为字节数组或者 json 字符串。

2.1、导入依赖

<!-- 对象序列化工具 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.3</version>
</dependency>

<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>

2.2、创建一个实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
<span class="hljs-keyword">private</span> String name;
<span class="hljs-keyword">private</span> <span class="hljs-type">int</span> age;
<span class="hljs-keyword">private</span> <span class="hljs-type">char</span> sex;
<span class="hljs-keyword">private</span> Date birthday;

}

2.3、操作测试

2.3.1、byte 数组方式
@Test
public void setObjByByte() {
    Jedis jedis = new Jedis("127.0.0.1", 6379);
<span class="hljs-type">String</span> <span class="hljs-variable">key</span> <span class="hljs-operator">=</span> <span class="hljs-string">"zhangsan"</span>;
<span class="hljs-type">Person</span> <span class="hljs-variable">person</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Person</span>(<span class="hljs-string">"张三"</span>, <span class="hljs-number">13</span>, <span class="hljs-string">'1'</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>());

<span class="hljs-type">byte</span>[] keyBytes = key.getBytes();
<span class="hljs-type">byte</span>[] personBytes = SerializationUtils.serialize(person);

jedis.set(keyBytes, personBytes);
jedis.close();

}

@Test
public void getObjByByte() {
Jedis jedis = new Jedis("127.0.0.1", 6379);

<span class="hljs-type">String</span> <span class="hljs-variable">key</span> <span class="hljs-operator">=</span> <span class="hljs-string">"zhangsan"</span>;
<span class="hljs-type">byte</span>[] keyBytes = key.getBytes();
<span class="hljs-type">byte</span>[] bytes = jedis.get(keyBytes);

<span class="hljs-type">Person</span> <span class="hljs-variable">person</span> <span class="hljs-operator">=</span> (Person) SerializationUtils.deserialize(bytes);
System.out.println(person);
jedis.close();

}

2.3.2、json 字符串方式
@Test
public void getObjByByte() {
    Jedis jedis = new Jedis("127.0.0.1", 6379);
<span class="hljs-type">String</span> <span class="hljs-variable">key</span> <span class="hljs-operator">=</span> <span class="hljs-string">"zhangsan"</span>;
<span class="hljs-type">byte</span>[] keyBytes = key.getBytes();
<span class="hljs-type">byte</span>[] bytes = jedis.get(keyBytes);

<span class="hljs-type">Person</span> <span class="hljs-variable">person</span> <span class="hljs-operator">=</span> (Person) SerializationUtils.deserialize(bytes);
System.out.println(person);
jedis.close();

}

@Test
public void setObjByJson() {
Jedis jedis = new Jedis("127.0.0.1", 6379);

<span class="hljs-type">String</span> <span class="hljs-variable">key</span> <span class="hljs-operator">=</span> <span class="hljs-string">"zhangsan"</span>;
<span class="hljs-type">Person</span> <span class="hljs-variable">person</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Person</span>(<span class="hljs-string">"张三"</span>, <span class="hljs-number">13</span>, <span class="hljs-string">'1'</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>());

jedis.set(key, JSON.toJSONString(person));

jedis.close();

}

@Test
public void getObjByJson() {
Jedis jedis = new Jedis("127.0.0.1", 6379);

<span class="hljs-type">String</span> <span class="hljs-variable">key</span> <span class="hljs-operator">=</span> <span class="hljs-string">"zhangsan"</span>;
<span class="hljs-type">String</span> <span class="hljs-variable">person</span> <span class="hljs-operator">=</span> jedis.get(key);

System.out.println(person);
jedis.close();

}

3、Jedis 连接池

3.1、默认配置方式

Jedis 默认连接池配置如下:

public class GenericObjectPoolConfig extends BaseObjectPoolConfig {
    public static final int DEFAULT_MAX_TOTAL = 8;
    public static final int DEFAULT_MAX_IDLE = 8;
    public static final int DEFAULT_MIN_IDLE = 0;
    private int maxTotal = 8;
    private int maxIdle = 8;
    private int minIdle = 0;
...

}

@Test
public void testPool1() {
    // 默认配置连接池
    JedisPool pool = new JedisPool("127.0.0.1", 6379);

    // 获取 Jedis 连接资源
    Jedis jedis = pool.getResource();

    // 执行操作
    String key = "zhangsan";
    String person = jedis.get(key);
    System.out.println(person);
    
    // 关闭连接
    jedis.close();
}

3.2、自定义配置

@Test
public void testPool2() {
    GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
    poolConfig.setMaxTotal(100); // 连接池容量
    poolConfig.setMaxIdle(10); // 最大空闲连接数
    poolConfig.setMinIdle(0); // 最小空闲连接数
    poolConfig.setMaxWaitMillis(2000); // 最大超时等待时间,当连接池空闲数为 0 时,程序等待的最大时间。 单位 ms
<span class="hljs-type">JedisPool</span> <span class="hljs-variable">pool</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">JedisPool</span>(poolConfig, <span class="hljs-string">"127.0.0.1"</span>, <span class="hljs-number">6379</span>);

<span class="hljs-type">Jedis</span> <span class="hljs-variable">jedis</span> <span class="hljs-operator">=</span> pool.getResource();

<span class="hljs-type">String</span> <span class="hljs-variable">key</span> <span class="hljs-operator">=</span> <span class="hljs-string">"zhangsan"</span>;
<span class="hljs-type">String</span> <span class="hljs-variable">person</span> <span class="hljs-operator">=</span> jedis.get(key);

System.out.println(person);

jedis.close();

}

4、Redis 管道

当客户端有大量重复命令提交到服务器时,为了提升执行效率,Redis 提供了管道的操作方式。

具体使用方法及管道使用前后对比如下:

@Test
public void testPipe() {
    GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
    poolConfig.setMaxTotal(100);
    poolConfig.setMaxIdle(10);
    poolConfig.setMinIdle(0);
    poolConfig.setMaxWaitMillis(2000);
    JedisPool pool = new JedisPool(poolConfig, "127.0.0.1", 6379);
<span class="hljs-type">Jedis</span> <span class="hljs-variable">jedis</span> <span class="hljs-operator">=</span> pool.getResource();

<span class="hljs-comment">// 获取管道</span>
<span class="hljs-type">Pipeline</span> <span class="hljs-variable">pipeline</span> <span class="hljs-operator">=</span> jedis.pipelined();

<span class="hljs-comment">// 程序开始执行时间戳</span>
<span class="hljs-type">long</span> <span class="hljs-variable">begin</span> <span class="hljs-operator">=</span> System.currentTimeMillis();
<span class="hljs-comment">// 不使用管道,执行自增10万次自增</span>
<span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">100000</span>; i++) {
    jedis.incr(<span class="hljs-string">"sth"</span>);
}
<span class="hljs-type">long</span> <span class="hljs-variable">end</span> <span class="hljs-operator">=</span> System.currentTimeMillis();
System.out.println(<span class="hljs-string">"without pipe: "</span> + (end - begin));

<span class="hljs-comment">// 程序开始执行时间戳</span>
<span class="hljs-type">long</span> <span class="hljs-variable">begin1</span> <span class="hljs-operator">=</span> System.currentTimeMillis();
<span class="hljs-comment">// 使用管道,执行自增10万此</span>
<span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">100000</span>; i++) {
    pipeline.incr(<span class="hljs-string">"foo"</span>);
}
<span class="hljs-type">long</span> <span class="hljs-variable">end1</span> <span class="hljs-operator">=</span> System.currentTimeMillis();
System.out.println(end1 - begin1);

jedis.close();

}

程序耗时对比: