Jedis 的 API 方法跟 Redis 的命令基本上完全一致,熟悉 Redis 的操作命令,自然就很容易使用 Jedis,因此官方也推荐 Java 使用 Jedis 来连接和操作 Redis 。由于我的电脑重装了系统,暂时没有安装虚拟机来运行 Linux 环境,因此临时采用 Windows 版本的 Redis 快速搭建环境。

本篇博客主要展示如何快速的使用 Jedis 连接和操作 Redis,在博客的最后面提供 demo 的源代码。

Jedis 的官网地址:https://github.com/redis/jedis


一、快速搭建 Redis 环境

Windows 版本的 Redis 的官网:https://github.com/microsoftarchive/redis

其实就是微软提供的 Redis 版本,目前最新版是 3.2.100,下载这个版本即可,下载地址为:

https://github.com/microsoftarchive/redis/releases/tag/win-3.2.100

下载 Redis-x64-3.2.100.zip 这个文件,解压缩即可,运行 redis-server.exe 即可。

默认情况下 Redis 没有设置密码,可以通过 redis.windows.conf 这个配置文件进行配置,有关 Redis 配置文件的细节,这里不做介绍,网上资料一大堆。

这里就以本机无密码的 Redis 快速搭建一个环境来介绍 Jedis 的使用。如果你想感觉每次手动启动 Redis 比较麻烦的话,可以将 Redis 安装成 Windows 服务,打开 cmd 命令行窗口,进入 Redis 的目录,运行以下命令安装 Redis 服务:

redis-server.exe  --service-install  redis.windows-service.conf

redis jedis版本匹配 jedis与redis对应版本_redis

然后进入服务管理器,启动 Redis 服务即可,如下图所示:

redis jedis版本匹配 jedis与redis对应版本_System_02

进入 Redis 的目录后可以运行下面的命令,也许对你有用:

# 卸载服务:
redis-server --service-uninstall

# 启动服务:
redis-server --service-start

# 停止服务:
redis-server --service-stop

# 重命名服务名称:
redis-server --service-name name


二、搭建工程

新建一个 maven 工程,并导入 Jedis 的 jar 包。

Jedis 的 jar 包地址为:https://mvnrepository.com/artifact/redis.clients/jedis

我导入的是最新的 Jedis 的 jar 包,另外为了方便测试,也导入了最新的 juint 的 jar 包,具体内容如下:

<!--导入 jedis 的 jar 包-->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.1.1</version>
</dependency>

<!--导入 junit 的 jar 包-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
</dependency>

配置好引用的 jar 包后,打开右侧的 Maven 窗口,刷新一下,这样 Maven 会自动下载所需的 jar 包文件。

搭建好的项目工程整体目录比较简单,具体如下图所示:

redis jedis版本匹配 jedis与redis对应版本_redis jedis版本匹配_03

项目工程结构简单介绍:

com.jobs.utils.jedisUtils 自己编写的使用 Jedis 访问 Redis 的工具类
resources 下的 redis.properties 是用来自定义 Jedis 连接池参数的配置文件

test 目录下的文件介绍:
com.jobs.JedisTest 类是专门用来编写 junit 单元测试方法,用来测试操作 Redis 的方法


三、细节展示

resources 下的 redis.properties 配置文件内容如下:

# 最大连接数
maxTotal=50
# 最大空闲连接数
maxIdel=10
# redis 服务器地址
host=localhost
# redis 服务器端口
port=6379

com.jobs.utils.jedisUtils 使用 Jedis 连接池编写的工具类内容如下:

package com.jobs.utils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.ResourceBundle;

public class jedisUtils {

    //定义 Jedis 连接池
    private static JedisPool jp;

    static {
        /*
            //第一种获取 properties 配置文件内容的方式
            InputStream is = jedisUtils.class
                .getClassLoader().getResourceAsStream("redis.properties");
            Properties prop = new Properties();
            try {
                prop.load(is);
            } catch (IOException e) {
                e.printStackTrace();
            }

            int maxTotal = Integer.parseInt(prop.getProperty("maxTotal"));
            int maxIdel = Integer.parseInt(prop.getProperty("maxIdel"));
            String host = prop.getProperty("host");
            int port = Integer.parseInt(prop.getProperty("port"));
         */

        //第二种获取 properties 配置文件内容的方式
        ResourceBundle bundle = ResourceBundle.getBundle("redis");
        int maxTotal = Integer.parseInt(bundle.getString("maxTotal"));
        int maxIdel = Integer.parseInt(bundle.getString("maxIdel"));
        String host = bundle.getString("host");
        int port = Integer.parseInt(bundle.getString("port"));

        //配置 Jedis 连接池
        JedisPoolConfig jpc = new JedisPoolConfig();
        jpc.setMaxTotal(maxTotal);
        jpc.setMaxIdle(maxIdel);
        jp = new JedisPool(jpc, host, port);

        // 如果 redis 有密码的话,使用这个初始化连接池(连接超时时间为 2000 毫秒)
        //jp = new JedisPool(jpc, host, port, 2000, "password");
        
        // 如果 redis 有密码的话,并且想直接连接到 redis 的某个库的话,使用该方法
        //jp = new JedisPool(jpc, host, port, 2000, "password",0);
    }

    //从连接池中获取 Jedis 连接对象
    public static Jedis getJedis() {
        return jp.getResource();
    }
}

com.jobs.JedisTest 类是专门用来测试操作 Redis 的方法类,具体内容如下:

package com.jobs;

import com.jobs.utils.jedisUtils;
import org.junit.Test;
import redis.clients.jedis.Jedis;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class JedisTest {

    //测试字符串 String 数据类型
    @Test
    public void testString() {
        Jedis jedis = jedisUtils.getJedis();

        //设置
        jedis.set("name", "候胖胖");
        jedis.set("age", "40");

        //获取
        String name = jedis.get("name");
        String age = jedis.get("age");

        System.out.println("name:" + name + ",age:" + age);
        jedis.close();
    }

    //测试列表 List 数据类型
    @Test
    public void testList() {

        Jedis jedis = jedisUtils.getJedis();
        //redis 的 list 可以作为队列使用
        //从列表右边添加数据
        jedis.rpush("fat", "任肥肥");
        jedis.rpush("fat", "侯胖胖");
        jedis.rpush("fat", "李墩墩");

        //获取列表的容量大小
        long fatCount = jedis.llen("fat");
        System.out.println("列表数量:" + fatCount);

        //从左侧逐个取数据
        for (int i = 0; i < fatCount; i++) {
            String fatMan = jedis.lpop("fat");
            System.out.println(fatMan);
        }

        jedis.close();
    }

    //测试散列 Hash 数据类型
    @Test
    public void testHash() {

        Jedis jedis = jedisUtils.getJedis();

        //redis 的 hash 比较适合存储对象数据
        Map<String, String> user1 = new HashMap<>();
        user1.put("name", "侯胖胖");
        user1.put("age", "40");
        user1.put("kg", "80");

        Map<String, String> user2 = new HashMap<>();
        user2.put("name", "任肥肥");
        user2.put("age", "38");
        user2.put("kg", "90");

        jedis.hmset("user1", user1);
        jedis.hmset("user2", user2);

        //修改第一个用户的年龄
        jedis.hset("user1", "age", "45");
        //修改第二个用户的体重
        jedis.hset("user2", "kg", "100");

        //获取两个对象的属性值
        Map<String, String> user111 = jedis.hgetAll("user1");
        Map<String, String> user222 = jedis.hgetAll("user2");
        System.out.println(user111);
        System.out.println(user222);

        jedis.close();
    }

    //测试集合 Set 数据类型
    @Test
    public void testSet() {
        Jedis jedis = jedisUtils.getJedis();

        //redis 的 set 跟 java 的 set 使用方式一样,重复的元素只保留一个
        jedis.sadd("aaa", "a", "b", "c", "x", "y", "z", "a", "x");
        jedis.sadd("bbb", "b", "c", "d", "e", "f", "y", "b", "e");

        //获取交集
        Set<String> sinter = jedis.sinter("aaa", "bbb");
        System.out.println("交集:" + sinter);

        //获取并集
        Set<String> sunion = jedis.sunion("aaa", "bbb");
        System.out.println("并集:" + sunion);

        //获取 aaa 相对于 bbb 的差集(存在于 aaa 但不存在与 bbb 的元素)
        Set<String> sdiff = jedis.sdiff("aaa", "bbb");
        System.out.println("aaa 相对于 bbb 的差集:" + sdiff);

        jedis.close();
    }

    //测试有序集合 Sorted Set (ZSet) 数据类型
    @Test
    public void testZset() {
        Jedis jedis = jedisUtils.getJedis();

        //redis 的 zSet 比较适合做排行榜

        //粉丝投票
        Map<String, Double> fans = new HashMap<>();
        fans.put("侯胖胖", 10d);
        fans.put("李墩墩", 7d);
        fans.put("任肥肥", 6d);
        fans.put("乔豆豆", 12d);
        fans.put("杨重重", 8d);
        jedis.zadd("vote", fans);

        //修改任肥肥的投票数
        jedis.zadd("vote", 9d, "任肥肥");

        //zSet 默认是按照分值的升序排列
        List<String> vote1 = jedis.zrange("vote", 0, -1);
        System.out.println("投票数量升序排列:" + vote1);

        //获取粉丝投票数量最多的前三个人
        List<String> vote2 = jedis.zrevrange("vote", 0, 2);
        System.out.println("投票数量倒序前 3 个人:" + vote2);

        jedis.close();
    }
}


到此为止,已经快速的演示了 Java 使用 Jedis 连接操作 Redis 常用的 5 种数据类型的示例。Jedis 提供的方法 API 基本上跟 Redis 的命令完全一致,有关 Redis 的命令使用细节,可以参考 Redis 的官网(https://redis.io)。