wordpress 网站改名,手机网页版微信下载,数据网站排名,idc机房托管费用Jedis 操作 Redis 数据结构全攻略 一 . 认识 RESP二 . 前置操作2.1 创建项目2.2 关于开放 Redis 端口的问题2.2.1 端口转发?2.2.2 端口配置 2.3 连接到 Redis 服务器 三 . 通用命令3.1 set 和 get3.2 exists 和 del3.3 keys3.4 expire、ttl、type 三 . string 相关命令3.1 mse… Jedis 操作 Redis 数据结构全攻略 一 . 认识 RESP二 . 前置操作2.1 创建项目2.2 关于开放 Redis 端口的问题2.2.1 端口转发?2.2.2 端口配置 2.3 连接到 Redis 服务器 三 . 通用命令3.1 set 和 get3.2 exists 和 del3.3 keys3.4 expire、ttl、type 三 . string 相关命令3.1 mset / mget3.2 getrange / setrange3.3 append3.4 incr / decr3.5 mset、mget3.6 append、incr、decr 四 . list 类型4.1 lpush、lrange、rpush4.2 lpop、rpop4.3 blpop 和 brpop4.4 llen 五 . set 类型5.1 sadd、smembers5.2 sismember5.3 scard5.4 spop5.5 sinter、sinterstore 六 . hash 类型6.1 hset、hget6.2 hexists6.3 hdel6.4 hkeys、hvals6.5 hmset、hmget 七 . zset 类型7.1 zadd、zrange7.2 zcard7.3 zrem7.4 zscore7.5 zrank Hello , 大家好 , 这个专栏给大家带来的是 Redis 系列 ! 我们之前主要学习的是各种 Redis 的基本操作所对应的命令 , 都是在 Redis 的客户端的命令行中手动执行的 , 但是这种方式并不是日常开发主要的形式 . 在日常工作中 , 最常见的就是用程序来操作 Redis , 利用 Redis 提供的 API 来实现一些功能 . 本专栏旨在为初学者提供一个全面的 Redis 学习路径从基础概念到实际应用帮助读者快速掌握 Redis 的使用和管理技巧。通过本专栏的学习能够构建坚实的 Redis 知识基础并能够在实际学习以及工作中灵活运用 Redis 解决问题 . 专栏地址 : Redis 入门实践 一 . 认识 RESP
那为什么我们通过代码就可以编写出一个自定义的 Redis 客户端呢 ? 我们先来回顾一个知识 , 在网络通信过程中 , 会用到很多的协议 , 从下往上的顺序依次是 :
物理层数据链路层 : 以太网协议网络层 : IP 协议传输层 : TCP/UDP 协议应用层 : 自定义协议 (比如 : HTTP 协议)
虽然业界有许多成熟的自定义协议 , 但是更多的时候 , 大家都会选择自定义应用层协议 , Redis 应用层的协议就是自定义的协议 . 那客户端按照应用层协议发送请求 , 服务器按照协议内容进行解析 , 再按照这个协议去构造响应 , 客户端去解析响应 . 那我们要想通信能够完成 , 就需要开发客户端和开发服务器的程序员都非常清楚协议的细节 . 那如果我们想要开发一个 Redis 客户端 , 也需要知道 Redis 的应用层协议 , 我们也可以从官网中获取到 Redis 的应用层协议 : https://redis.io/docs/reference/protocol-spec 那 RESP 就是 Redis 的自定义的应用层协议的名字 我们来阅读以下这篇文档 简单好实现 : Redis 的客户端使用一种叫做 RESP 的协议来去跟 Redis 服务器进行通讯 . 可以快速进行解析 : RESP 可以识别不同的类型 , 比如整型、字符串、数组 . 客户端和服务器是基于 TCP 协议进行连接的 , 但是其实跟 TCP 关系没多大 , 只是借助 TCP 这个平台 Redis 客户端请求和响应是一问一答类型的 客户端给服务器发送一个请求 , 服务器返回给客户端一个响应 客户端给服务器发送的是 Redis 命令 , 以 bulk strings 数组的形式发送的 那不同的命令返回结果也不同 , 有的命令直接返回 ok , 有的命令可能返回整数 … 如果是简单的字符串 , 用 ‘’ 表示 , 如果是简单的错误 , 用 ‘-’ 表示 … 下面还介绍了一个样例 , 服务端返回 OK 时候的表示 那服务器返回 OK 就会返回这串字符串 , 将这串字符串写入到 TCP 的 socket 中
因此 , Redis 的客户端和服务器要做的工作 , 就是
按照上述格式构造出字符串 , 写入 socket 中从 socket 中读取字符串 , 按照上述格式进行解析 那我们介绍 RESP 只是希望大家了解一下 Redis 底层是怎样通信的 , 并不影响后续代码的编写
二 . 前置操作
Redis 在官网上公开了自定义的应用层协议 : RESP , 那任何一个第三方都可以根据约定好的协议就可以实现出一个和 Redis 服务器通信的客户端程序 . 那也有很多大佬已经实现好了现成的客户端程序 , 我们可以直接调用 , 就不必再关心里面的细节了 . 在 Java 中 , 比较常用的是 Jedis , 因为他所提供的 API 和 Redis 的命令非常相似 , 十分好上手 . 那我们创建一个 Maven 项目 , 来去演示一系列的操作
2.1 创建项目
打开我们的 IDEA 然后在 pom.xml 中引入 Jedis 的依赖
!-- https://mvnrepository.com/artifact/redis.clients/jedis --
dependencygroupIdredis.clients/groupIdartifactIdjedis/artifactIdversion4.4.3/version
/dependency然后我们就可以新建一个类 , 来去模拟 Jedis 的操作了
2.2 关于开放 Redis 端口的问题
我们开发代码 , 一般都使用 Windows 系统 , 但是我们的 Redis 是存在云服务器上的 , 要是使用 127.0.0.1 访问到云服务器上面的 Redis 肯定是实现不了的 ❓ 那我们修改成云服务器的外网 IP 再去访问行不 ? 也是不可以的 , 我们 Redis 的默认端口 6379 默认是被云服务器的防火墙给保护起来的 . ❓ 那我们再把 6379 给放开不就好了 ? 不可以 ! 千万不要这样做 ! Redis 是非常容易被黑客攻击的 , Redis 的端口一旦公开到网上 , 就特别容易被入侵 ! 虽然我们之前开放过 tomcat 的端口 , 这是因为 tomcat 端口的安全性非常高 . 但是 Redis 的 6379 端口 , 安全性非常差 , 一旦你开了 , 不出 3 天 , 服务器就要死翘翘 . 那我给 Redis 换个端口 , 是不是就安全了 ? - 掩耳盗铃 , 还是不安全的 . 那我们有两种方案解决 :
直接让 Java 程序也在 Linux 上面运行 [不推荐] 需要我们把代码编写完毕之后 , 打成一个 jar 包 , 然后把 jar 包拷贝到云服务器上去执行 比较麻烦 配置 SSH 端口转发 , 把云服务器的 Redis 端口 , 映射到本地主机 [推荐]
2.2.1 端口转发?
我们的 Windows 主机和云服务器是通过 SSH 连接起来的 那一个 Linux 主机上 , 需要映射的 Windows 设备有很多 , SSH 也有可能需要来给多个端口传递数据 , 这个时候 , 为了区分不同的端口 , 往往会把服务器的端口在本地用另外一个端口来表示 这样就实现了本地和云服务器端口的对应 只要咱们进行简单的配置 , 后续就把服务器的端口当成一个本地端口来使用即可
2.2.2 端口配置
打开我们的 XShell SSH 端口转发 SSH SSH 隧道 只有当 SSH 连接上了之后 , 端口转发才生效 那把 SSH 连接断开 , 端口转发自然就失效了 那我们现在就可以检验一下是否生效了 使用 netstat 命令查看本地 8888 端口是否被绑定 那当我们配置了端口转发之后 ,如果之前配置过了端口转发 , 一定要断开之前的连接 , 重新连接才能生效 那我们后续 , 在 Java 代码中 , 通过 127.0.0.1:8888 就可以操作到我们的云服务器的 Redis 了 , 同时 , 外面的客户端是无法直接访问云服务器的 6379 端口的 我们再介绍一下 XTerminal 的配置方法
2.3 连接到 Redis 服务器
要想连接到 Redis 的服务器 , 我们需要使用 JedisPool 这样的对象 . 在 JedisPool 的构造方法中 , 就需要指定我们需要连接的服务器地址 注意服务器地址应该设置成本机的环回 IP 我们配置的端口映射 import redis.clients.jedis.JedisPool;public class RedisDemo {public static void main(String[] args) {// 连接到 Redis 服务器上JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);}
}
接下来我们就需要从 JedisPool 这个 Redis 连接池中取出一个连接 , 连接用完之后需要释放 所以我们可以直接选择 try-with-resources 这样的方式自动释放 import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;public class RedisDemo {public static void main(String[] args) {// 连接到 Redis 服务器上JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);// 从 Redis 连接池中取出一个连接try (Jedis jedis jedisPool.getResource()) {}}
}
那之后我们就可以使用 Redis 的各种命令了 我们以 Redis 中的 ping 命令来测试连接是否成功
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;public class RedisDemo {public static void main(String[] args) {// 连接到 Redis 服务器上JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);// 从 Redis 连接池中取出一个连接try (Jedis jedis jedisPool.getResource()) {// Redis 的各种命令, 都可以对应到 Jedis 对象的各种方法// 验证 Redis 的连通性String pong jedis.ping();System.out.println(pong);}}
} 注意 : 我们要确保云服务器的 Redis 的配置文件里面的配置是正确的 输入 cd /etc/redis/ , 然后用 vim 打开 redis.conf 判断这两个位置是否跟我的一致 , 不一致的话就要修改一下 控制台打印 PONG 代表连接成功
三 . 通用命令
3.1 set 和 get
我们先来模拟一下最基本的 get 和 set 的使用
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;public class RedisDemo {/*** 模拟 get 和 set 的使用*/public static void test01(Jedis jedis) {System.out.println(模拟 get 和 set 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 模拟 set 的使用jedis.set(k1, v1);jedis.set(k2, v2);// 模拟 get 的使用String v1 jedis.get(k1);String v2 jedis.get(k2);System.out.println(value1 v1);System.out.println(value2 v2);}public static void main(String[] args) {// 连接到 Redis 服务器上JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);// 从 Redis 连接池中取出一个连接try (Jedis jedis jedisPool.getResource()) {test01(jedis);}}
}
那 set 命令还有一些其他版本 我们可以看到 , set 方法还可以有第三个参数 那我们就可以先创建一个 SetParams 对象 , 然后调用 ex / nx / xx 等方法
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;public class RedisDemo {/*** 模拟 get 和 set 的使用*/public static void test01(Jedis jedis) {System.out.println(模拟 get 和 set 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 模拟 set 的使用jedis.set(k1, v1);jedis.set(k2, v2);// 模拟 get 的使用String v1 jedis.get(k1);String v2 jedis.get(k2);System.out.println(value1 v1);System.out.println(value2 v2);// set 的其它参数SetParams params new SetParams();params.ex(10);// 设置超时时间为 10sparams.xx();// 存在才去修改(更新)// params.nx();// 不存在才去创建jedis.set(k1, v3, params);// 此时 k1 存在, 可以被修改System.out.println(jedis.get(k1));}public static void main(String[] args) {// 连接到 Redis 服务器上JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);// 从 Redis 连接池中取出一个连接try (Jedis jedis jedisPool.getResource()) {test01(jedis);}}
}
我们可以看一下运行结果
3.2 exists 和 del
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;public class RedisDemo {/*** 模拟 exists 和 del 的使用*/public static void test02(Jedis jedis) {System.out.println(模拟 exists 和 del 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 构造数据jedis.set(k1, 111);jedis.set(k2, 222);// 判断对应的 key 是否存在boolean result jedis.exists(k1);System.out.println(k1 是否存在 : result);// true// 删除对应键值对// del 方法返回值为 long, 代表删除成功的个数long result2 jedis.del(k2);System.out.println(删除成功的个数 : result2);// 1// 再去判断 k2 是否存在boolean result3 jedis.exists(k2);System.out.println(k2 是否存在 : result3);// false// 可以删除多个 key// 但是仍然只会返回删除成功的个数long result4 jedis.del(k1, k2, k3);System.out.println(删除成功的个数 : result4);// 1}public static void main(String[] args) {// 连接到 Redis 服务器上JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);// 从 Redis 连接池中取出一个连接try (Jedis jedis jedisPool.getResource()) {test02(jedis);}}
}
3.3 keys
我们之前学习 keys 命令的时候 , 他有很多 pattern . 那我们先来看一下最基本的情况 : keys * , 查询所有的 key
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;import java.util.Set;public class RedisDemo {/*** 模拟 keys 的使用*/public static void test03(Jedis jedis) {System.out.println(模拟 keys 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 构造数据jedis.set(k1, 111);jedis.set(k2, 222);jedis.set(k3, 333);jedis.set(k4, 444);// 模拟 keys 的使用// 返回值是 Set 类型SetString keys jedis.keys(*);// 相当于 keys *System.out.println(keys);}public static void main(String[] args) {// 连接到 Redis 服务器上JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);// 从 Redis 连接池中取出一个连接try (Jedis jedis jedisPool.getResource()) {test03(jedis);}}
}
运行结果 : 我们需要知道的是 , keys 命令的返回值是 Set 类型 之所以使用 Set 类型而不是 List 类型的原因是 : Redis 中要求 key 是不能重复的 , 并且对于 key 的先后顺序也并没有要求 , 所以使用 Set 类型会更合适一些
3.4 expire、ttl、type
我们先来看 ttl 和 expire 的使用方法
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;import java.util.Set;public class RedisDemo {/*** 模拟 expire、ttl 的使用*/public static void test04(Jedis jedis) {System.out.println(模拟 expire、ttl、type 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 构造数据jedis.set(k1, 111);// 设置过期时间jedis.expire(k1, 10);// 设置过期时间为 10s// 获取剩余时间// ttl 返回值为 longlong time jedis.ttl(k1);System.out.println(当前键值对剩余时间为 time);// 等待 3stry {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}// 休眠 3s 之后继续获取剩余时间time jedis.ttl(k1);System.out.println(当前键值对剩余时间为 time);}public static void main(String[] args) {// 连接到 Redis 服务器上JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);// 从 Redis 连接池中取出一个连接try (Jedis jedis jedisPool.getResource()) {test04(jedis);}}
}
我们可以看一下运行结果 这就代表我们 expire 设置生效了 , 并且休眠 3s 之后还能正确获取剩余时
那接下来我们再来看 type 命令
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;import java.util.Set;public class RedisDemo {/*** 模拟 type 的使用*/public static void test05(Jedis jedis) {System.out.println(模拟 type 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 构造数据jedis.set(k1, 111);// 设置成字符串类型String type1 jedis.type(k1);System.out.println(当前数据的类型为: type1);jedis.lpush(k2,111,222,333);String type2 jedis.type(k2);System.out.println(当前数据的类型为: type2);jedis.hset(k3,f1,111);String type3 jedis.type(k3);System.out.println(当前数据的类型为: type3);jedis.sadd(k4,111,222,333);String type4 jedis.type(k4);System.out.println(当前数据的类型为: type4);jedis.zadd(k5,10,zhangsan);String type5 jedis.type(k5);System.out.println(当前数据的类型为: type5);}public static void main(String[] args) {// 连接到 Redis 服务器上JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);// 从 Redis 连接池中取出一个连接try (Jedis jedis jedisPool.getResource()) {test05(jedis);}}
}
我们可以看一下运行结果
三 . string 相关命令
我们给大家介绍这几个命令 :
针对多个 key 进行操作 : mset / mget获取 / 设置字符串指定范围内容 : getrange / setrange拼接字符串 : append对数据进行自增自减 : incr / decr
3.1 mset / mget
注意 : mget 的返回值是 List , 而不是 Set
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class RedisDemoString {// mget mset 的用法public static void test1(Jedis jedis) {// 1. 清空数据库// 避免上一组的测试数据影响到下一组的测试结果jedis.flushDB();// 2. 设置多个键值对jedis.mset(key1, value1, key2, value2, key3, value3);// 3. 获取多个键值对// 返回值: ListListString values jedis.mget(key1, key2, key3);System.out.println(values : values);}public static void main(String[] args) {// 1. 连接到 Redis 服务器上JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);// 2. 创建 Jedis 对象try (Jedis jedis jedisPool.getResource()) {test1(jedis);}}
} 那我们的 value 与上面设置的 set 的顺序是一一对应的 那假如我们中间获取一个不存在的 key , 会发生什么 ? 如果获取不存在的值 , 就会打印 null , 这也说明了有几个参数 , 就有几个返回结果
3.2 getrange / setrange
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class RedisDemoString {// getrange / setrange 的使用public static void test2(Jedis jedis) {// 1. 清空数据库// 避免上一组的测试数据影响到下一组的测试结果jedis.flushDB();// 2. 添加数据jedis.set(key, HelloWorld!);// 3. 获取指定区间的顺序// 左闭右闭区间String result jedis.getrange(key, 2, 5);System.out.println(result result);// 4. 设置指定区间的值jedis.setrange(key, 2, 666);System.out.println(修改之后的值: jedis.get(key));}public static void main(String[] args) {// 1. 连接到 Redis 服务器上JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);// 2. 创建 Jedis 对象try (Jedis jedis jedisPool.getResource()) {test2(jedis);}}
} 3.3 append
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class RedisDemoString {// append 的使用public static void test3(Jedis jedis) {// 1. 清空数据库// 避免上一组的测试数据影响到下一组的测试结果jedis.flushDB();// 2. 模拟数据jedis.set(key, Hello);// 3. 追加数据jedis.append(key, World);// 4. 查看追加后的数据System.out.println(修改之后的值 : jedis.get(key));}public static void main(String[] args) {// 1. 连接到 Redis 服务器上JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);// 2. 创建 Jedis 对象try (Jedis jedis jedisPool.getResource()) {test3(jedis);}}
} 3.4 incr / decr
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class RedisDemoString {// incr / decr 的使用public static void test4(Jedis jedis) {// 1. 清空数据库// 避免上一组的测试数据影响到下一组的测试结果jedis.flushDB();// 2. 模拟数据// 这次要模拟一个整数的数据jedis.set(key, 100);// 3. 自增操作// 返回自增之后的值long result1 jedis.incr(key);System.out.println(自增操作返回的值: result1);// 预期是 101// 4. 获取 key 的值System.out.println(此时 key 的值为: jedis.get(key));// 预期是 101// 5. 自减操作long result2 jedis.decr(key);System.out.println(自减操作返回的值: result2);// 预期是 100// 6. 获取 key 的值System.out.println(此时 key 的值为: jedis.get(key));// 预期是 100}public static void main(String[] args) {// 1. 连接到 Redis 服务器上JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);// 2. 创建 Jedis 对象try (Jedis jedis jedisPool.getResource()) {test4(jedis);}}
} 那 incr 和 decr 还可以指定增加或者删除的值 , 使用 incrby 和 decrby
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class RedisDemoString {// incr / decr 的使用public static void test4(Jedis jedis) {// 1. 清空数据库// 避免上一组的测试数据影响到下一组的测试结果jedis.flushDB();// 2. 模拟数据// 这次要模拟一个整数的数据jedis.set(key, 100);// 3. 自增操作// 返回自增之后的值long result1 jedis.incr(key);System.out.println(自增操作返回的值: result1);// 预期是 101// 4. 获取 key 的值System.out.println(此时 key 的值为: jedis.get(key));// 预期是 101// 5. 自减操作long result2 jedis.decr(key);System.out.println(自减操作返回的值: result2);// 预期是 100// 6. 获取 key 的值System.out.println(此时 key 的值为: jedis.get(key));// 预期是 100// 7. 指定增加的值long result3 jedis.incrBy(key, 10);System.out.println(指定增加的值最后变成了: result3);// 预期是 110// 8. 获取 key 的值System.out.println(此时 key 的值为: jedis.get(key));// 预期是 110// 9. 指定减少的值long result4 jedis.decrBy(key, 5);System.out.println(指定减少的值最后变成了: result4);// 预期是 105// 10. 获取 key 的值System.out.println(此时 key 的值为: jedis.get(key));// 预期是 105}public static void main(String[] args) {// 1. 连接到 Redis 服务器上JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);// 2. 创建 Jedis 对象try (Jedis jedis jedisPool.getResource()) {test4(jedis);}}
} 3.5 mset、mget
我们先来看 mset 和 mget 这一组 mset 可以设置多组键值对 , mget 可以获取多组键值对
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class StringDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test01(jedis);}}private static void test01(Jedis jedis) {System.out.println(模拟 mset mget 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 模拟 mset 设置多组数据jedis.mset(k1,v1,k2,v2,k3,v3);// 模拟 mget 获取多组数据ListString values1 jedis.mget(k1,k2,k3);System.out.println(value 的值为 : values1);}
}
那我们来看一下运行结果 那要注意的是 , mget 的返回值是 List 而不是 Set 之前学习 keys 命令的时候 , 他的返回值是 Set , 是因为 key 要求不能重复 . 而我们的 value 是可以重复的 , 所以使用 List 来去接收 那如果我们获取的多个键值对中某个 key 不存在 , 该怎样返回呢 ?
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class StringDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test01(jedis);}}private static void test01(Jedis jedis) {System.out.println(模拟 mset mget 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 模拟 mset 设置多组数据jedis.mset(k1,v1,k2,v2,k3,v3);// 模拟 mget 获取多组数据ListString values1 jedis.mget(k1,k2,k3);System.out.println(value 的值为 : values1);// 如果某个 key 在 Redis 中不存在// 则对应的位置用 null 表示ListString values2 jedis.mget(k1,k2,k100,k3);System.out.println(value 的值为 : values2);}
}
我们可以通过运行结果来看一下 那我们就知道了 , 如果某个 key 在 Redis 上不存在 , 则对应的 value 用 null 来表示
那我们再来看一下 getrange 和 setrange getrange 的作用是获取到 [start , end] 区间内的数据 setrange 的作用是从 start 位置开始 , 修改内容为指定的字符串
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class StringDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test02(jedis);}}private static void test02(Jedis jedis) {System.out.println(模拟 getrange 和 setrange 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 构造测试数据jedis.set(key,abcdefghigklmn);// 获取 [start,end] 区间的数据String str1 jedis.getrange(key,2,5);System.out.println(str1);// 从 start 位置开始, 修改内容为指定的字符串// 从下标为 2 的位置开始修改, 修改成 hahahajedis.setrange(key,2,hahaha);String str2 jedis.get(key);System.out.println(str2);}
}
我们可以来看一下运行结果
3.6 append、incr、decr
append 的作用是拼接字符串
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class StringDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test03(jedis);}}private static void test03(Jedis jedis) {System.out.println(模拟 append 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 构造数据jedis.set(key, Hello);// 拼接字符串jedis.append(key, World);String value jedis.get(key);System.out.println(value value);}
}
我们可以看一下运行结果
我们再来看一下 incr 和 decr 的用法
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class StringDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test04(jedis);}}private static void test04(Jedis jedis) {System.out.println(模拟 incr 和 decr 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 构造数据jedis.set(key, 100);// 模拟 incr 的使用// incr 返回值类型为 long, 代表自增后的结果long result1 jedis.incr(key);System.out.println(自增之后的值为 : result1);String value1 jedis.get(key);System.out.println(value 的值为 : value1);// 模拟 decr 的使用// decr 返回值类型为 long, 代表自减后的结果long result2 jedis.decr(key);System.out.println(自增之后的值为 : result2);String value2 jedis.get(key);System.out.println(value 的值为 : value2);}
} 还有其他的比如 incrby、incrbyfloat 命令 , 我们就不进行演示了
四 . list 类型
4.1 lpush、lrange、rpush
lpush 的作用是向列表中添加元素 (头插法) lrange 的作用是可以获取到列表中的元素 rpush 就相当于尾插法
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class ListDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test01(jedis);}}private static void test01(Jedis jedis) {System.out.println(模拟 lpush 和 lrange 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 头插法向列表中插入元素// 返回值为插入成功之后 list 的长度jedis.lpush(key, 111, 222, 333);// 获取列表中的元素// 返回值为 ListListString result1 jedis.lrange(key, 0, -1);System.out.println(头插法之后的列表为 : result1);// 尾插法向列表中插入元素jedis.rpush(key, 555, 666);ListString result2 jedis.lrange(key, 0, -1);System.out.println(尾插法之后的列表为 : result2);}
}
我们可以看一下运行结果
4.2 lpop、rpop
lpop 就相当头头删法 rpop 就相当于尾删法
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class ListDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test02(jedis);}}private static void test02(Jedis jedis) {System.out.println(模拟 lpush 和 lrange 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 构造列表中的数据jedis.rpush(key, 111, 222, 333, 444);// 从列表尾部删除元素String result1 jedis.rpop(key);System.out.println(尾删法删除的值为 : result1);result1 jedis.rpop(key);System.out.println(尾删法删除的值为 : result1);// 从列表头部删除元素String result2 jedis.lpop(key);System.out.println(头删法删除的值为 : result2);result2 jedis.lpop(key);System.out.println(头删法删除的值为 : result2);// 此时列表为空// 继续获取就会获取到 nullresult1 jedis.rpop(key);System.out.println(尾删法删除的值为 : result1);result2 jedis.lpop(key);System.out.println(头删法删除的值为 : result2);}
} 4.3 blpop 和 brpop
blpop 和 brpop 就相当于阻塞版本的 lpop 和 rpop
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class ListDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test03(jedis);}}private static void test03(Jedis jedis) {System.out.println(模拟 blpop 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 我们先在列表为空的时候去执行以下 blpop// 第一个参数: 超时时间(单位: s)// 第二个参数: 要获取的 key// 返回值是一个二元组, 使用 List 接收// 一个是从哪个 key 获取到的结果, 一个是删除的元素是什么ListString result jedis.blpop(3, key);System.out.println(从 result.get(0) 中获取到的结果);System.out.println(删除的元素为 : result.get(1));}
}
此时由于我们的 Redis 中并没有数据 , 所以 blpop 就会发生阻塞等待 , 超过设置的时间就会返回 null 导致代码出现空指针异常 那我们可以模拟一下其他客户端插入元素的情况
4.4 llen
llen 的作用是获取到列表的元素个数
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.List;public class ListDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test04(jedis);}}private static void test04(Jedis jedis) {System.out.println(模拟 llen 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 构造列表中的数据jedis.rpush(key, 111, 222, 333, 444);// 获取列表中的元素个数long len jedis.llen(key);System.out.println(列表中的元素个数为 len);}
} 五 . set 类型
5.1 sadd、smembers
sadd 的作用是向集合中添加元素 smembers 是获取到集合中的元素
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.Set;public class SetDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test01(jedis);}}private static void test01(Jedis jedis) {System.out.println(模拟 sadd、smembers 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 向集合中添加元素jedis.sadd(key, 111, 222, 333, 444);// 获取集合中的元素// smembers 返回值是一个 Set// 注意: smembers 顺序是无序的, 与插入顺序无关SetString result jedis.smembers(key);System.out.println(集合中的元素为 : result);}
} 5.2 sismember
sismember 的作用是判断元素是否在集合中存在
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.Set;public class SetDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test02(jedis);}}private static void test02(Jedis jedis) {System.out.println(模拟 sismember 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 向集合中添加元素jedis.sadd(key, 111, 222, 333, 444);// 判断元素是否存在// sismember 返回值为布尔类型boolean result1 jedis.sismember(key, 111);System.out.println(result1);// key 不存在就会返回 falseboolean result2 jedis.sismember(key100, 111);System.out.println(result2);// value 不存在也会返回 falseboolean result3 jedis.sismember(key, 666);System.out.println(result3);}} 5.3 scard
scard 是用来获取集合中的元素个数
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.Set;public class SetDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test03(jedis);}}private static void test03(Jedis jedis) {System.out.println(模拟 scard 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 向集合中添加元素jedis.sadd(key, 111, 222, 333, 444);// 获取集合中的元素个数long len jedis.scard(key);System.out.println(集合中的元素个数为 : len);}
} 5.4 spop
spop 的作用是随机删除一个元素
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.Set;public class SetDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test04(jedis);}}private static void test04(Jedis jedis) {System.out.println(模拟 spop 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 向集合中添加元素jedis.sadd(key, 111, 222, 333, 444);// spop 的作用是随机删除一个元素// 返回值是被删除的元素String result jedis.spop(key);System.out.println(随机删除的值为 : result);}
}
我们可以多次运行来看一下删除的值是否是固定的
5.5 sinter、sinterstore
sinter 和 sinterstore 的作用是用来求多个集合的交集
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.Set;public class SetDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test05(jedis);}}private static void test05(Jedis jedis) {System.out.println(模拟 sinter、sinterstore 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 向集合中添加元素jedis.sadd(key1, 111, 222, 333);jedis.sadd(key2, 111, 222, 444);// 求多个集合的交集SetString result1 jedis.sinter(key1, key2);System.out.println(sinter 交集的结果为 : result1);// 将交集的结果保存到另外的 key 中// sinterstore 的返回值表示交集的个数long len jedis.sinterstore(dest, key1, key2);System.out.println(sinterstore 交集的长度为 : len);SetString result2 jedis.smembers(dest);System.out.println(sinterstore 交集的结果为 : result2);}
} 六 . hash 类型
6.1 hset、hget
hset 的作用是向哈希中添加元素 hget 是用来获取哈希中的元素的 我们先来看一下 hset 他有两种版本 , 一种是正常添加 key-field-value , 另一种是将多组 field-value 打包成一个 Map 进行插入 我们分别来演示
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.HashMap;
import java.util.Map;public class HashDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test01(jedis);}}private static void test01(Jedis jedis) {System.out.println(模拟 hset 和 hget 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 向哈希中添加一组元素jedis.hset(k1, f1, 111);// 向哈希中添加多组元素// 将多组 field-value 打包成一个 MapMapString, String fields new HashMap();fields.put(f2, 222);fields.put(f3, 333);jedis.hset(k1, fields);// 获取哈希中的元素String result1 jedis.hget(k1, f1);System.out.println(哈希中的元素 : result1);// 如果 key 不存在, 就会获取失败String result2 jedis.hget(k100, f1);System.out.println(哈希中的元素 : result2);// 如果 field 不存在, 就会获取失败String result3 jedis.hget(k1, f100);System.out.println(哈希中的元素 : result3);}
} 6.2 hexists
hexists 的作用是用来判断元素是否存在
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.HashMap;
import java.util.Map;public class HashDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test02(jedis);}}private static void test02(Jedis jedis) {System.out.println(模拟 hexists 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 向哈希中添加多组元素// 将多组 field-value 打包成一个 MapMapString, String fields new HashMap();fields.put(f1, 111);fields.put(f2, 222);fields.put(f3, 333);jedis.hset(k1, fields);// 判断某个元素是否存在// 返回值是布尔类型boolean result1 jedis.hexists(k1, f1);System.out.println(该元素是否存在 : result1);// 如果 key 不存在, 就会返回 falseboolean result2 jedis.hexists(k100, f1);System.out.println(该元素是否存在 : result2);// 如果 field 不存在, 就会返回 falseboolean result3 jedis.hexists(k1, f100);System.out.println(该元素是否存在 : result3);}
} 6.3 hdel
hedel 的作用是删除指定的 field
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.HashMap;
import java.util.Map;public class HashDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test03(jedis);}}private static void test03(Jedis jedis) {System.out.println(模拟 hdel 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 向哈希中添加多组元素// 将多组 field-value 打包成一个 MapMapString, String fields new HashMap();fields.put(f1, 111);fields.put(f2, 222);fields.put(f3, 333);jedis.hset(k1, fields);// hdel 的作用是删除指定的 key 下面的 field// 返回值代表删除成功的个数long delNum jedis.hdel(k1, f1, f2, f100);System.out.println(删除成功的个数为 : delNum);// 此时再去判断 f1 和 f2 是否还存在boolean result1 jedis.hexists(k1, f1);System.out.println(f1 是否存在 : result1);boolean result2 jedis.hexists(k1, f2);System.out.println(f2 是否存在 : result2);}
} 6.4 hkeys、hvals
hkeys 是用来获取哈希中所有的 key hvals 是用来获取海中所有的 val
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;public class HashDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test04(jedis);}}private static void test04(Jedis jedis) {System.out.println(模拟 hkeys、hvals 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 向哈希中添加多组元素// 将多组 field-value 打包成一个 MapMapString, String fields new HashMap();fields.put(f1, 111);fields.put(f2, 222);fields.put(f3, 333);jedis.hset(k1, fields);// hkeys 用来获取所有的 field// 返回值是 Set 类型SetString result1 jedis.hkeys(k1);System.out.println(keys : result1);// hvals 用来获取所有的 value// 返回值是 List 类型ListString result2 jedis.hvals(k1);System.out.println(vals : result2);}
} 那要注意的是 , hkeys 的返回值类型为 Set , hvals 的返回值类型为 List 这是因为哈希中要求 key 不能重复 , 所以使用 Set 来去接收 ; 而 value 是可以重复的 , 所以使用 List 来去接收 6.5 hmset、hmget
hmset 的作用与 hset 差不多 , 都是用来添加哈希的 , 并且添加多组哈希都需要用到 Map 辅助 hmget 的作用是获取多组哈希的值
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;public class HashDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test05(jedis);}}private static void test05(Jedis jedis) {System.out.println(模拟 hmset、hmget 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// hmset 可以添加多组哈希// 但仍然需要将多组 field-value 打包成一个 MapMapString, String map new HashMap();map.put(f1, 111);map.put(f2, 222);map.put(f3, 333);jedis.hmset(k1, map);// hmget 可以获取多组哈希ListString values jedis.hmget(k1, f1, f2, f3, f4);System.out.println(values : values);}
} 那他的特点就是会根据 field 的顺序来去打印 value 的顺序 , 也就是说 field-value 是严格对应的 hkeys 和 hvals 则不是 , 他们都是随机打印的 , 并不能一一对应 七 . zset 类型
7.1 zadd、zrange
zadd 是向有序集合中添加元素 zrange 是用来获取有序集合的所有元素
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.HashMap;
import java.util.List;
import java.util.Map;public class ZSetDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test01(jedis);}}private static void test01(Jedis jedis) {System.out.println(模拟 zadd、zrange 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 向 zset 中添加一组元素jedis.zadd(key, 10.0, zhangsan);// 也可以向 zset 中添加多组元素// 但是也需要借助 Map 来去设置 score 和 valueMapString, Double map new HashMap();map.put(lisi, 20.0);map.put(wangwu, 30.0);jedis.zadd(key, map);// 获取 zset 中的元素// 返回值类型为 ListListString members jedis.zrange(key, 0, -1);System.out.println(有序集合中的元素为 : members);}
} 如果我们想既获取到 members , 又获取到 scores , 那就需要使用 zrangewithscores 这个方法了 但是 zrangewithscores 的返回值类型有些特殊 , 需要我们留意一下 那这个 Tuple 是 Jedis 提供给我们的数据类型 , 代表元组 (也就是一组数据)
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.resps.Tuple;import java.util.HashMap;
import java.util.List;
import java.util.Map;public class ZSetDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test01(jedis);}}private static void test01(Jedis jedis) {System.out.println(模拟 zadd、zrange 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 向 zset 中添加一组元素jedis.zadd(key, 10.0, zhangsan);// 也可以向 zset 中添加多组元素// 但是也需要借助 Map 来去设置 score 和 valueMapString, Double map new HashMap();map.put(lisi, 20.0);map.put(wangwu, 30.0);jedis.zadd(key, map);// 获取 zset 中的元素ListString members jedis.zrange(key, 0, -1);System.out.println(有序集合中的元素为 : members);// 既获取 members, 又获取 scoresListTuple memberswithscores jedis.zrangeWithScores(key, 0, -1);System.out.println(有序集合中的元素为 : memberswithscores);// 获取其中某一个元素String member memberswithscores.get(0).getElement();double score memberswithscores.get(0).getScore();System.out.println(第一个元素 : member , 他的成绩为 : score);}
} 7.2 zcard
zcard 是用来统计有序集合的元素个数的
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.resps.Tuple;import java.util.HashMap;
import java.util.List;
import java.util.Map;public class ZSetDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test02(jedis);}}private static void test02(Jedis jedis) {System.out.println(模拟 zcard 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 构造多组有序集合数据jedis.zadd(key, 10, zhangsan);jedis.zadd(key, 20, lisi);jedis.zadd(key, 30, wangwu);// 获取有序集合的元素个数long len jedis.zcard(key);System.out.println(有序集合的元素个数为 : len);}
} 7.3 zrem
zrem 用来删除指定元素
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.resps.Tuple;import java.util.HashMap;
import java.util.List;
import java.util.Map;public class ZSetDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test03(jedis);}}private static void test03(Jedis jedis) {System.out.println(模拟 zrem 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 构造多组有序集合数据jedis.zadd(key, 10, zhangsan);jedis.zadd(key, 20, lisi);jedis.zadd(key, 30, wangwu);// 删除指定元素// 可以删除多组数据, 返回值代表删除成功的个数long remNum jedis.zrem(key, zhangsan, lisi);System.out.println(删除成功的元素个数 : remNum);// 获取剩余元素ListTuple result jedis.zrangeWithScores(key, 0, -1);System.out.println(剩余元素 : result);}
} 7.4 zscore
zscore 的作用是根据 member 来去找到对应的 score
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.resps.Tuple;import java.util.HashMap;
import java.util.List;
import java.util.Map;public class ZSetDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test04(jedis);}}private static void test04(Jedis jedis) {System.out.println(模拟 zscore 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 构造多组有序集合数据jedis.zadd(key, 10, zhangsan);jedis.zadd(key, 20, lisi);jedis.zadd(key, 30, wangwu);// 根据 member 获取对应的分数double score1 jedis.zscore(key, zhangsan);System.out.println(score score1);}
} 但是有一个需要注意的位置 : 就是我们在接收 score 的时候 , 使用的是 double 来去接收的 如果 member 存在 , 那么正常返回成绩 , 没什么问题 ; 但是如果 member 不存在呢 ? member 不存在 , zscore 就会返回 null , 用 double 去接收 null 是会触发空指针异常的 . 所以我们尽量谁用包装类来去接收
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.resps.Tuple;import java.util.HashMap;
import java.util.List;
import java.util.Map;public class ZSetDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test04(jedis);}}private static void test04(Jedis jedis) {System.out.println(模拟 zscore 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 构造多组有序集合数据jedis.zadd(key, 10, zhangsan);jedis.zadd(key, 20, lisi);jedis.zadd(key, 30, wangwu);// 根据 member 获取对应的分数// 注意: 请使用包装类进行接收, 避免触发空指针异常Double score1 jedis.zscore(key, zhangsan);System.out.println(score score1);}
} 7.5 zrank
zrank 的作用是获取到某个 member 他所对应的排名 (下标)
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.resps.Tuple;import java.util.HashMap;
import java.util.List;
import java.util.Map;public class ZSetDemo {public static void main(String[] args) {JedisPool jedisPool new JedisPool(tcp://127.0.0.1:8888);try (Jedis jedis jedisPool.getResource()) {test05(jedis);}}private static void test05(Jedis jedis) {System.out.println(模拟 zrank 的使用);// 避免上一组测试的残留数据影响到本组测试结果// 所以需要先清空一下数据库jedis.flushDB();// 构造多组有序集合数据jedis.zadd(key, 10, zhangsan);jedis.zadd(key, 20, lisi);jedis.zadd(key, 30, wangwu);// 获取某个 member 的排名// 注意: 返回值用 Long 包装类接收, 避免空指针异常Long rank jedis.zrank(key, lisi);System.out.println(rank : rank);}
} 这篇文章知识含量超级大 , 如果对大家有帮助的话 , 还请一键三连~ 文章转载自: http://www.morning.rzcbk.cn.gov.cn.rzcbk.cn http://www.morning.bwjws.cn.gov.cn.bwjws.cn http://www.morning.hpggl.cn.gov.cn.hpggl.cn http://www.morning.qtwd.cn.gov.cn.qtwd.cn http://www.morning.pljdy.cn.gov.cn.pljdy.cn http://www.morning.ishoufeipin.cn.gov.cn.ishoufeipin.cn http://www.morning.qykxj.cn.gov.cn.qykxj.cn http://www.morning.lmfmd.cn.gov.cn.lmfmd.cn http://www.morning.mfzyn.cn.gov.cn.mfzyn.cn http://www.morning.lkbyq.cn.gov.cn.lkbyq.cn http://www.morning.qqzdr.cn.gov.cn.qqzdr.cn http://www.morning.crfyr.cn.gov.cn.crfyr.cn http://www.morning.tqrbl.cn.gov.cn.tqrbl.cn http://www.morning.rkqzx.cn.gov.cn.rkqzx.cn http://www.morning.czcbl.cn.gov.cn.czcbl.cn http://www.morning.ypbdr.cn.gov.cn.ypbdr.cn http://www.morning.lrybz.cn.gov.cn.lrybz.cn http://www.morning.tfcwj.cn.gov.cn.tfcwj.cn http://www.morning.hmqmm.cn.gov.cn.hmqmm.cn http://www.morning.yqtry.cn.gov.cn.yqtry.cn http://www.morning.rbjth.cn.gov.cn.rbjth.cn http://www.morning.jlgjn.cn.gov.cn.jlgjn.cn http://www.morning.nfzw.cn.gov.cn.nfzw.cn http://www.morning.ndmbd.cn.gov.cn.ndmbd.cn http://www.morning.tpqzs.cn.gov.cn.tpqzs.cn http://www.morning.bsjpd.cn.gov.cn.bsjpd.cn http://www.morning.srrrz.cn.gov.cn.srrrz.cn http://www.morning.bpmth.cn.gov.cn.bpmth.cn http://www.morning.krqhw.cn.gov.cn.krqhw.cn http://www.morning.twgzq.cn.gov.cn.twgzq.cn http://www.morning.pcjw.cn.gov.cn.pcjw.cn http://www.morning.tqjks.cn.gov.cn.tqjks.cn http://www.morning.pbxkk.cn.gov.cn.pbxkk.cn http://www.morning.cqyhdy.cn.gov.cn.cqyhdy.cn http://www.morning.stxg.cn.gov.cn.stxg.cn http://www.morning.kdfqx.cn.gov.cn.kdfqx.cn http://www.morning.ghcfx.cn.gov.cn.ghcfx.cn http://www.morning.cpfbg.cn.gov.cn.cpfbg.cn http://www.morning.blfgh.cn.gov.cn.blfgh.cn http://www.morning.yntsr.cn.gov.cn.yntsr.cn http://www.morning.dqpd.cn.gov.cn.dqpd.cn http://www.morning.xclgf.cn.gov.cn.xclgf.cn http://www.morning.jcpq.cn.gov.cn.jcpq.cn http://www.morning.lfdrq.cn.gov.cn.lfdrq.cn http://www.morning.zrpys.cn.gov.cn.zrpys.cn http://www.morning.qztsq.cn.gov.cn.qztsq.cn http://www.morning.nbdtdjk.cn.gov.cn.nbdtdjk.cn http://www.morning.nbwyk.cn.gov.cn.nbwyk.cn http://www.morning.ptwrz.cn.gov.cn.ptwrz.cn http://www.morning.lzrpy.cn.gov.cn.lzrpy.cn http://www.morning.dkbsq.cn.gov.cn.dkbsq.cn http://www.morning.mmzhuti.com.gov.cn.mmzhuti.com http://www.morning.rbxsk.cn.gov.cn.rbxsk.cn http://www.morning.jntcr.cn.gov.cn.jntcr.cn http://www.morning.rhmt.cn.gov.cn.rhmt.cn http://www.morning.kpwcx.cn.gov.cn.kpwcx.cn http://www.morning.wyjpt.cn.gov.cn.wyjpt.cn http://www.morning.hbpjb.cn.gov.cn.hbpjb.cn http://www.morning.lbgfz.cn.gov.cn.lbgfz.cn http://www.morning.tdgwg.cn.gov.cn.tdgwg.cn http://www.morning.ryxbz.cn.gov.cn.ryxbz.cn http://www.morning.lhxdq.cn.gov.cn.lhxdq.cn http://www.morning.hbnwr.cn.gov.cn.hbnwr.cn http://www.morning.pmdlk.cn.gov.cn.pmdlk.cn http://www.morning.hjrjy.cn.gov.cn.hjrjy.cn http://www.morning.gccdr.cn.gov.cn.gccdr.cn http://www.morning.hkcjx.cn.gov.cn.hkcjx.cn http://www.morning.tsnwf.cn.gov.cn.tsnwf.cn http://www.morning.zlgr.cn.gov.cn.zlgr.cn http://www.morning.hsjfs.cn.gov.cn.hsjfs.cn http://www.morning.mgbcf.cn.gov.cn.mgbcf.cn http://www.morning.qpntn.cn.gov.cn.qpntn.cn http://www.morning.dqrhz.cn.gov.cn.dqrhz.cn http://www.morning.lmhwm.cn.gov.cn.lmhwm.cn http://www.morning.wrwcf.cn.gov.cn.wrwcf.cn http://www.morning.ygqhd.cn.gov.cn.ygqhd.cn http://www.morning.inheatherskitchen.com.gov.cn.inheatherskitchen.com http://www.morning.nzkc.cn.gov.cn.nzkc.cn http://www.morning.rahllp.com.gov.cn.rahllp.com http://www.morning.btrfm.cn.gov.cn.btrfm.cn