【Redis学习笔记06】Jedis客户端(下)

Jedis客户端

1. 命令

1.1 Hash类型

Hash类型相信大家并不陌生,许多编程语言都有对应数据结构的实现,可能叫做哈希、字典、映射、关联数组,是相当重要的!

  • 在实际开发中非常常用
  • 在面试中也是高频考点
1.1.1 常见命令
  1. HSET命令:

语法格式:HSET key field value [field value...]
说明:设置某个key的某一个field的值为value,可以批量插入
时间复杂度:O(K),K为待插入的field数量
返回值:插入成功的field数量

127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> HSET k1 f1 v1
(integer) 1
127.0.0.1:6379> HSET k1 f2 v2 f3 v3
(integer) 2
127.0.0.1:6379> HGETALL k1
1) "f1"
2) "v1"
3) "f2"
4) "v2"
5) "f3"
6) "v3"
  1. HGET命令:

语法格式:HGET key field
说明:获取指定key的指定field的值,如果key或者field不存在则返回nil
时间复杂度:O(1)
返回值:

  • 如果存在则返回对应值
  • 如果key或者field不存在则返回nil
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> HSET k1 f1 v1
(integer) 1
127.0.0.1:6379> HGET k1 f1
"v1"
127.0.0.1:6379> HGET k1 f2
(nil)
127.0.0.1:6379> HGET k2 f1
(nil)
  1. HEXISTE命令:

语法格式:HEXISTS key field
说明:查询某个key下是否存在某个field,如果存在返回1,如果key不存在或者field不存在返回0
时间复杂度:O(1)
返回值:

  • 如果存在,则返回1
  • 如果key或者field不存在,则返回0
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> HSET k1 f1 v1
(integer) 1
127.0.0.1:6379> HEXISTS k1 f1
(integer) 1
127.0.0.1:6379> HEXISTS k1 f2
(integer) 0
127.0.0.1:6379> HEXISTS k2 f1
(integer) 0
  1. HDEL命令:

语法格式:HDEL key field [field...]
说明:删除key下的一个或多个field,返回删除成功的数目
时间复杂度:O(K),K为指定的field的数量
返回值:成功删除的field数量

127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> HSET k1 f1 v1 f2 v2 f3 v3
(integer) 3
127.0.0.1:6379> HDEL k1 f1 f3
(integer) 2
127.0.0.1:6379> HGETALL k1
1) "f2"
2) "v2"
127.0.0.1:6379> HDEL k1 f2 f3 f4
(integer) 1
127.0.0.1:6379> HGETALL k1
(empty array)
  1. HKEYS命令:

语法格式:HKEYS key
说明:展示key下全部的field字段
时间复杂度:O(N),N为field字段的数量
返回值:key下field组成的列表

127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> HSET k1 f1 11 f2 22 f3 33
(integer) 3
127.0.0.1:6379> HKEYS k1
1) "f1"
2) "f2"
3) "f3"
  1. HVALS命令:

语法格式:HVALS key
说明:展示key下全部的field对应的value
时间复杂度:O(N),N为field字段的数量
返回值:key下field对应的value组成的列表

127.0.0.1:6379> 
127.0.0.1:6379> keys *
1) "k1"
127.0.0.1:6379> HVALS k1
1) "11"
2) "22"
3) "33"
  1. HGETALL命令:

语法格式:HGETALL key
说明:展示key下全部的field:value键值对
时间复杂度:O(N),N为field字段的数量
返回值:key下全部的field:value键值对列表

127.0.0.1:6379> keys *
1) "k1"
127.0.0.1:6379> HKEYS k1
1) "f1"
2) "f2"
3) "f3"
127.0.0.1:6379> HVALS k1
1) "11"
2) "22"
3) "33"
127.0.0.1:6379> HGETALL k1
1) "f1"
2) "11"
3) "f2"
4) "22"
5) "f3"
6) "33"

说明:上述例如HKEYS、HVALS、HGETALL等命令与KEY *类似,均小心在生产环境下使用,如果当前field数目过多,就会导致redis服务器阻塞!!!

  1. HMGET命令:

语法格式:HMGET key field [field...]
说明:查询某个key下指定的field对应的值
时间复杂度:O(K),K为指定的field的数量
返回值:返回指定的field的值对应的列表,如果没有则返回nil

127.0.0.1:6379> keys *
1) "k1"
127.0.0.1:6379> HGETALL k1
1) "f1"
2) "11"
3) "f2"
4) "22"
5) "f3"
6) "33"
127.0.0.1:6379> HMGET k1 f1 f3
1) "11"
2) "33"
  1. HLEN命令:

语法格式:HLEN key
说明:查询某个key下的field的数量
时间复杂度:O(1)
返回值:某个key下field的数量

127.0.0.1:6379> keys *
1) "k1"
127.0.0.1:6379> HGETALL k1
1) "f1"
2) "11"
3) "f2"
4) "22"
5) "f3"
6) "33"
127.0.0.1:6379> HLEN k1
(integer) 3
127.0.0.1:6379> 

  1. HSETNX命令:

语法格式:HSETNX key field value
说明:向某个key插入一对field:value键值对数据,只有原先不存在才进行插入
时间复杂度:O(1)
返回值:插入成功返回1,插入失败返回0

127.0.0.1:6379> keys *
1) "k1"
127.0.0.1:6379> HGETALL k1
1) "f1"
2) "11"
3) "f2"
4) "22"
5) "f3"
6) "33"
127.0.0.1:6379> HSETNX k1 f4 44
(integer) 1
127.0.0.1:6379> HGET k1 f4
"44"
127.0.0.1:6379> HSETNX k1 f4 55
(integer) 0
127.0.0.1:6379> HGET k1 f4
"44"
  1. HSTRLEN命令:

语法格式:HSTRLEN key field
说明:获取某个key下的某个field的value的长度(单位为字节)
时间复杂度:O(1)
返回值:返回key下某个field(字符串类型)的长度,单位为字节

127.0.0.1:6379> keys *
1) "k1"
127.0.0.1:6379> HGETALL k1
1) "f1"
2) "0"
127.0.0.1:6379> HSET k1 f2 abc
(integer) 1
127.0.0.1:6379> HSTRLEN k1 f2
(integer) 3
1.1.2 计数命令
  1. HINCRBY命令:

语法格式:HINCRBY key field increment
说明:将某个key的某个field的值+increment(increment可为负)
时间复杂度:O(1)
返回值:返回修改后的新值

127.0.0.1:6379> flushall 
OK
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> HSET k1 f1 11
(integer) 1
127.0.0.1:6379> HINCRBY k1 f1 20
(integer) 31
127.0.0.1:6379> HGET k1 f1
"31"
127.0.0.1:6379> HINCRBY k1 f1 -20
(integer) 11
127.0.0.1:6379> HGET k1 f1
"11"
  1. HINCRBYFLOAT命令:

语法格式:HINCRBYFLOAT key field increment
说明:将某个key的某个field的值+increment(increment可为负)
时间复杂度:O(1)
返回值:返回修改后的新值

127.0.0.1:6379> keys *
1) "k1"
127.0.0.1:6379> HGETALL k1
1) "f1"
2) "11"
127.0.0.1:6379> HINCRBYFLOAT k1 f1 0.5
"11.5"
127.0.0.1:6379> HGET k1 f1
"11.5"
127.0.0.1:6379> HINCRBYFLOAT k1 f1 -10
"1.5"
127.0.0.1:6379> HINCRBYFLOAT k1 f1 -1.5
"0"
127.0.0.1:6379> HGET k1 f1
"0"

1.2 ZSet类型

1.2.1 普通命令
  1. ZADD命令:

语法格式:ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member...]
说明:添加或者更新指定的元素以及与之关联的分数到有序集合中,分数应该为double类型,-inf以及+inf也是允许的
时间复杂度:O(logN)
返回值:本次添加成功的元素个数
可选项:

  • [XX | NX] : XX只更新已经存在的key,而NX如果已经存在就不更新,单纯的创建
  • [LT | GT]:LT:表示分数小于,GT:表示分数大于
  • [CH]:修改返回值的含义为新增或者更新的总个数
  • [INCR]:将分数加上指定的值
127.0.0.1:6379> ZADD k1 10 zhangsan 20 lisi 30 wangwu
3
127.0.0.1:6379> ZRANGE k1 0 -1 withscores
zhangsan
10
lisi
20
wangwu
30
127.0.0.1:6379> ZADD k1 NX 50 wangwu
0
127.0.0.1:6379> ZRANGE k1 0 -1 withscores
zhangsan
10
lisi
20
wangwu
30
127.0.0.1:6379> ZADD k1 NX 50 zhaoliu
1
127.0.0.1:6379> ZRANGE k1 0 -1 withscores
zhangsan
10
lisi
20
wangwu
30
zhaoliu
50
127.0.0.1:6379> ZADD k1 XX 70 laoqi
0
127.0.0.1:6379> ZADD k1 XX 60 zhaoliu
0
127.0.0.1:6379> ZRANGE k1 0 -1 withscores
zhangsan
10
lisi
20
wangwu
30
zhaoliu
60
127.0.0.1:6379> ZADD k1 XX CH 70 zhaoliu
1
127.0.0.1:6379> ZRANGE k1 0 -1 withscores
zhangsan
10
lisi
20
wangwu
30
zhaoliu
70
  1. ZCARD命令:

语法格式:ZCARD key
说明:返回指定有序集合的元素个数
时间复杂度:O(1)
返回值:有序集合中的元素个数

127.0.0.1:6379> ZADD k1 10 zhangsan 20 lisi 30 wangwu
3
127.0.0.1:6379> ZRANGE k1 0 -1 withscores
zhangsan
10
lisi
20
wangwu
30
127.0.0.1:6379> ZCARD k1
3
  1. ZCOUNT命令:

语法格式:ZCOUNT key min max
说明:返回分数在min以及max区间的元素个数,默认情况下min,max均包含,(min max表示(min, max],(min (max表示(min, max)
时间复杂度:O(log(N))
返回值:符合分数区间的元素个数

127.0.0.1:6379> keys *

127.0.0.1:6379> ZADD k1 10 zhangsan 20 lisi 30 wangwu
3
127.0.0.1:6379> ZRANGE k1 0 -1 withscores
zhangsan
10
lisi
20
wangwu
30
127.0.0.1:6379> ZCOUNT k1 10 30
3
127.0.0.1:6379> ZCOUNT k1 (10 30
2
127.0.0.1:6379> ZCOUNT k1 (10 (30
1
  1. ZRANGE命令:

语法格式:ZRANGE key start stop [withscores]
说明:返回区间为[start, stop]内的元素列表,升序排列,withscores可以携带分数返回
时间复杂度:(O(logN + M))
返回值:指定区间的元素列表

127.0.0.1:6379> keys *

127.0.0.1:6379> ZADD k1 10 one 20 two 30 three
3
127.0.0.1:6379> ZRANGE k1 0 -1 
one
two
three
127.0.0.1:6379> ZRANGE k1 0 -1 withscores
one
10
two
20
three
30
  1. ZREVRANGE命令:

语法格式:ZREVRANGE key start stop [withscores]
说明:返回区间为[start, stop]内的元素列表,降序排列,withscores可以携带分数返回
时间复杂度:O(log(N) + M)
返回值:指定区间的元素列表

127.0.0.1:6379> keys *

127.0.0.1:6379> ZADD k1 10 zhangsan 20 lisi 30 wangwu
3
127.0.0.1:6379> ZREVRANGE k1 0 -1
wangwu
lisi
zhangsan
127.0.0.1:6379> ZREVRANGE k1 0 -1 withscores
wangwu
30
lisi
20
zhangsan
10
  1. ZRANGEBYSCORE命令:

语法格式:ZRANGEBYSCORE key min max [withscores]
说明:返回分数区间在[min, max]之间的元素列表
时间复杂度:O(log(N) + M)
返回值:指定区间内元素列表

127.0.0.1:6379> keys *
k1
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> ZADD k1 10 zhangsan 20 lisi 30 wangwu
3
127.0.0.1:6379> ZRANGEBYSCORE k1 20 30 withscores
lisi
20
wangwu
30
  1. ZPOPMAX命令:

语法格式:ZPOPMAX key [count]
说明:删除并返回分数最高的count个元素
时间复杂度:(O(logN * M)) ,Redis在此处没有优化
返回值:分数和元素列表

127.0.0.1:6379> keys *

127.0.0.1:6379> ZADD k1 10 zhangsan 20 lisi 30 wangwu
3
127.0.0.1:6379> ZPOPMAX k1 
wangwu
30
127.0.0.1:6379> ZPOPMAX k1 2
lisi
20
zhangsan
10
  1. BZPOPMAX命令:

语法格式:BZPOPMAX key [key...] timeout
说明:BZPOPMAX的阻塞版本,监听多个key的有序集合,timeout为超时时间
时间复杂度:O(logN)
返回值:key以及元素以及对应分数
:::success
ZPOPMIN、BZPOPMIN与上述类似
:::

  1. ZRANK命令:

语法格式:ZRANK key member
说明:返回member对应的排名(升序)
时间复杂度:O(logN)
返回值:member升序排名

127.0.0.1:6379> keys *

127.0.0.1:6379> ZADD k1 10 zhangsan 20 lisi 30 wangwu
3
127.0.0.1:6379> ZRANK k1 wangwu
2
127.0.0.1:6379> ZRANGE k1 0 -1 withscores
zhangsan
10
lisi
20
wangwu
30
  1. ZREVRANK命令:

语法格式:ZREVRANK key member
说明:返回member对应的排名(降序)
时间复杂度:(OlogN)
返回值:member降序排名

127.0.0.1:6379> keys *

127.0.0.1:6379> ZADD 10 zhangsan 20 lisi 30 wangwu
ERR syntax error

127.0.0.1:6379> ZADD k1 10 zhangsan 20 lisi 30 wangwu
3
127.0.0.1:6379> ZRANGE k1 0 -1 withscores
zhangsan
10
lisi
20
wangwu
30
127.0.0.1:6379> ZREVRANK k1 wangwu
0
  1. SCORE命令:

语法格式:ZSCORE key
说明:返回指定元素的分数
时间复杂度:O(1)
返回值:memebr对应分数

127.0.0.1:6379> keys *
k1
127.0.0.1:6379> ZRANGE k1 0 -1 withscores
zhangsan
10
lisi
20
wangwu
30
127.0.0.1:6379> ZSCORE k1 wangwu
30
1.2.2 Zset内部编码方式

Zset内部编码方式主要有以下两种:

  1. ziplist:压缩列表,当有序集合中存储元素数量较少,不超过zset-max-ziplist-entries配置项(默认128),同时每个元素的大小不超过zset-max-ziplist-value配置(默认为64)则使用ziplist进行存储,目的是为了节省内存空间
  2. skiplist:跳表,当存储元素个数或者大小不满足ziplist条件时,就会转换为skiplist进行实现

1)当元素个数较少并且单个元素占用空间不高的情况

127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> zadd k1 10 zhangsan
(integer) 1
127.0.0.1:6379> OBJECT ENCODING k1
"ziplist"

2)当单个元素占用空间过高的情况:

127.0.0.1:6379> zadd k2 32 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
(integer) 1
127.0.0.1:6379> OBJECT ENCODING k2
"skiplist"

关于跳表:
简单来说,跳表就是一个"复杂链表",查询元素的时间复杂度可以达到O(logN),相比于树形结构(平衡二叉树),跳表的好处是可以支持范围查询

1.2.3 Zset应用场景

Zset作为一个有序集合,最重要的应用场景就是作为 **“排行榜系统”,**例如:

  1. 微博热榜
  2. 游戏天梯榜
  3. 成绩排行榜

关键就在于需要快速对用于排行的"分数"实时更新,而Zset一些命令例如:ZSCOREZRANKZINCRBY能够快速修改信息以及重新排名
微博热榜:
微博热榜相对于游戏天梯榜更为复杂,因为游戏天梯榜依据玩家排位分作为score,但是微博热榜中的热度值score有多方面影响因素,例如:点赞数、转发量、浏览量、评论量,我们可以根据不同的维度计算出不同的分数score,然后依据权重值的不同借助ZINTERSTORE等命令进行加权处理进行集合间运算,后续也就可以依据所得的分数score进行排序

1.3 Redis其余数据类型

上面我们介绍了String、List、Hash、Set、Zset等五种常见的数据结构,但是Redis除此之外还提供了另外的数据结构,但是这些数据结构只是针对某些特殊场景适用,应用广泛性远远不及上述五种数据结构

1.3.1 stream类型

steam类型可以用作模拟实现事件传播机制
所谓事件:
事件其实大家并不陌生:

  • 对于像epoll等IO多路复用模型就是借助了事件,例如当网卡上有可读可写的数据时,就会借助事件回调机制通知应用程序进行处理
  • 在前端JS领域,onClick="doClick()"等点击事件也使用到了事件概念

在Redis中的stream可以看做是一个"阻塞队列",是用来实现"消息队列"的重要基础,可以看做是"BLPOP","BRPOP"的增强版本。

1.3.2 Geospatial类型

是Redis内部的一个存储地理位置的数据结构,即存储坐标信息(经纬度)
Geospatial类型常常用于地图等功能中,可以给定一个坐标和一个半径,查找附近范围内存储的点信息

1.3.3 HyperLogLog类型

应用场景:估算集合中的元素个数
前面我们介绍过Set类型一大重要应用场景就是进行"UV"统计,但是如果用户量个数非常庞大,比如有1亿用户,那么每个用户存储一个userId(8字节)就是8亿字节=0.8GB,但是HyperLogLog可以只最多用12KB的内存进行存储,关键就在于HyperLogLog不存储元素本身,而是借助 “**位运算” **操作存储数据特征,这样一来就能够在新增元素的同时判断该元素是否新增过(存在误差)
HyperLogLog VS Set
HyperLogLog:

  • 优点:占用存储空间小
  • 缺点:无法给出具体的存储元素,存在误差

Set:

  • 优点:内部保存了具体的元素,且无误差
  • 缺点:占用存储空间相对较大
1.3.4 Bitmaps类型

位图:本质上还是一个集合,可以看做是Set类型对于整型所做的特化版本,目的依旧是为了节省空间,例如需要存储元素10,使用位图就是00000000 00000000 00000010 00000000
Bitmaps VS HyperLogLog

  • bitmaps不仅仅存储元素特征,也存储元素具体类型(占用空间更大)
  • bitmaps针对整型,而HyperLogLog可以针对字符串类型
1.3.5 Bitfields类型

Bitfields类似于C语言结构体中的位段:可以理解为是一串二进制序列(字节数组),同时可以对于其中的几位进行算数、读取、修改操作,目的仍旧是节省空间!

2. Java客户端操作redis

Java生态丰富,自定义的客户端非常多,常见的有Jedis、Lettuce、以及Spring整合后的RedisTemplate,但是对于初学者而言,从Jedis开始入门学习是非常容易上手的,因为Jedis中的API与原生Redis命令高度一致。

2.1 引入Jedis依赖

此处引入如下依赖:

  • Jedis:Java操作Redis客户端
  • Junit:方便编写单元测试
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>4.4.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

2.2 配置Xshell端口转发

  1. 操作步骤:1. 打开Xshell点击属性 => 2. 配置SSH隧道 => 3. 配置如下端口转发内容

image.png

  1. 打开windows cmd程序输入:netstat -ano | findstr 8888如果观察如下

image.png

  1. 确保redis.conf配置中设置protect-mode为no以及bind为0.0.0.0

2.3 编写Demo

使用Jedis的步骤如下:

  1. 创建JedisPool连接池对象(配置redis服务器所在IP地址+端口号)
  2. 从JedisPool连接池中取出连接对象,并操作其中提供的API方法
  3. 解析响应内容
/**
 * 测试Redis连通性
 * @author 米饭好好吃
 */
@Test
public void testPing() {
    // 1. 创建JedisPool
    JedisPool pool = new JedisPool("tcp://127.0.0.1:8888");
    // 2. 获取连接对象
    try(Jedis jedis = pool.getResource();) {
        // 设置密码(如果有)
        jedis.auth("xxxxxx");
        // 3. 调用API-ping
        String pong = jedis.ping();
        // 4. 解析响应结果
        System.out.println(pong);
    }
}

2.4 测试Hash类型

对于Redis中Hash类型,常见的命令有:hset、hget、hmset、hmget、hexists、hdel、hkeys、hvals、hgetall、hincrby、hincrbyfloat…
下面我们简单介绍一些命令如何使用Jedis客户端调用:

  1. 测试HSET、HGET命令:
/**
 * 测试Redis中的Hash类型
 * @author 米饭好好吃
 */
public class TestHash {
    private JedisPool pool;

    @Before
    public void init() {
        pool = new JedisPool("tcp://127.0.0.1:8888");
    }

    @Test
    public void testHSETAndHGET() {
        // 1. 获取到Jedis连接对象
        try(Jedis jedis = pool.getResource();) {
            // 设置密码(如果有的话)
            // jedis.auth("xxxxxx");
            // 2. 清空数据库
            jedis.flushDB();
            // 3. 测试HSET、HGET命令
            jedis.hset("k1", "f1", "11");
            String res = jedis.hget("k1", "f1");
            System.out.println("k1 f1: " + res);
        }
    }
}

  1. 测试HMSET、HMGET命令:
/**
 * 测试HMSET、HMGET命令
 */
@Test
public void testHMSETAndHMGET() {
    // 1. 获取Jedis连接对象
    try (Jedis jedis = pool.getResource();) {
        // 设置密码(如果有的话)
        // jedis.auth("xxxxxx");
        // 2. 清空数据库
        jedis.flushDB();
        // 3. 测试HMSET、HMGET命令
        Map<String, String> map = new HashMap<>();
        map.put("f1", "11");
        map.put("f2", "22");
        map.put("f3", "33");
        jedis.hmset("k1", map);
        List<String> list = jedis.hmget("k1", "f1", "f2", "f3");
        System.out.println("list: " + list);
    }
}
  1. 测试HEXISTS、HDEL命令:
/**
 * 测试HEXISTS以及HDEL命令
 */
@Test
public void testHEXISTSAndHDEL() {
    // 1. 获取Jedis连接对象
    try (Jedis jedis = pool.getResource();) {
        // 设置密码(如果有的话)
        // jedis.auth("xxxxxx");
        // 2. 清空数据库
        jedis.flushDB();
        // 3. 测试HEXISTS、HDEL命令
        jedis.hset("k1", "f1", "11");
        jedis.hset("k1", "f2", "22");
        jedis.hset("k1", "f3", "33");
        boolean exists = jedis.hexists("k1", "f1");
        System.out.println("exists: " + exists);
        jedis.hdel("k1", "f1");
        exists = jedis.hexists("k1", "f1");
        System.out.println("exists: " + exists);
    }
}
  1. 测试HKEYS、HVALS、HGELALL命令:
/**
 * 测试HKEYS、HVALS、HGETALL命令
 */
@Test
public void testHKEYSAndHVALSAndHGETALL() {
    // 1. 获取Jedis连接对象
    try (Jedis jedis = pool.getResource();) {
        // 设置密码(如果有的话)
        // jedis.auth("xxxxxx");
        // 2. 清空数据库
        jedis.flushDB();
        // 3. 测试HKEYS、HVALS、HGETALL命令
        jedis.hset("k1", "f1", "11");
        jedis.hset("k1", "f2", "22");
        jedis.hset("k1", "f3", "33");
        Set<String> hKeys = jedis.hkeys("k1");
        List<String> hValues = jedis.hvals("k1");
        Map<String, String> map = jedis.hgetAll("k1");
        System.out.println("hkeys: " + hKeys);
        System.out.println("hvals: " + hValues);
        System.out.println("hgetalls: " + map);
    }
}
  1. 测试HLEN命令:
/**
 * 测试HLEN命令
 */
@Test
public void testHLEN() {
    // 1. 获取Jedis连接对象
    try (Jedis jedis = pool.getResource();) {
        // 设置密码(如果有的话)
        // jedis.auth("xxxxxx");
        // 2. 清空数据库
        jedis.flushDB();
        // 3. 测试HLEN命令
        jedis.hset("k1", "f1", "11");
        jedis.hset("k1", "f2", "22");
        jedis.hset("k1", "f3", "33");
        long len = jedis.hlen("k1");
        System.out.println("len: " + len);
    }
}
  1. 测试HINCRBY命令:
/**
 * 测试HINCRBY命令
 */
@Test
public void testHINCRBY() {
    // 1. 获取Jedis连接对象
    try (Jedis jedis = pool.getResource();) {
        // 设置密码(如果有的话)
        // jedis.auth("xxxxxx");
        // 2. 清空数据库
        jedis.flushDB();
        // 3. 测试HINCR命令
        jedis.hset("k1", "f1", "10");
        jedis.hincrBy("k1", "f1", 5);
        String res = jedis.hget("k1", "f1");
        System.out.println("k1 f1:  " + res);
    }
}

2.5 测试ZSet类型

对于Redis中ZSet类型,常见的命令有:zadd、zrange、zscore、zrank、zrem、zpopmax、zpopmin、zcard、zinterstore、zunionstore、zdiffstore…
下面我们简单介绍一些命令如何使用Jedis客户端调用:

  1. 测试ZADD、ZRANGE命令:
/**
 * 测试ZADD、ZRANGE命令
 */
@Test
public void testZADDAndZRANGE() {
    // 1. 获取Jedis连接对象
    try (Jedis jedis = pool.getResource();) {
        // 设置密码(如果有的话)
        // jedis.auth("xxxxxx");
        // 2. 清空数据库
        jedis.flushDB();
        // 3. 测试ZADD、ZRANGE命令
        jedis.zadd("k1", 10, "zhangsan");
        jedis.zadd("k1", 20, "lisi");
        jedis.zadd("k1", 30, "wangwu");
        List<String> list = jedis.zrange("k1", 0, -1);
        System.out.println("list: " + list);
        List<Tuple> tuples = jedis.zrangeWithScores("k1", 0, -1);
        System.out.println("tuples: " + tuples);
    }
}
  1. 测试ZSCORE、ZRANK命令:
/**
 * 测试ZRANK、ZSCORE命令
 */
@Test
public void testZSCOREAndZRANK() {
    // 1. 获取Jedis连接对象
    try (Jedis jedis = pool.getResource();) {
        // 设置密码(如果有的话)
        // jedis.auth("xxxxxx");
        // 2. 清空数据库
        jedis.flushDB();
        // 3. 测试ZSCORE、ZRANK命令
        jedis.zadd("k1", 10, "zhangsan");
        jedis.zadd("k1", 20, "lisi");
        jedis.zadd("k1", 30, "wangwu");
        Double score = jedis.zscore("k1", "lisi");
        System.out.println("score: " + score);
        Long rank = jedis.zrank("k1", "wangwu");
        System.out.println("rank: " + rank);
    }
}
  1. 测试ZREM、ZCARD命令:
/**
 * 测试ZCARD、ZREM命令
 */
@Test
public void testZCARDAndZREM() {
    // 1. 获取Jedis连接对象
    try (Jedis jedis = pool.getResource();) {
        // 设置密码(如果有的话)
        // jedis.auth("xxxxxx");
        // 2. 清空数据库
        jedis.flushDB();
        // 3. 测试ZCARD命令
        jedis.zadd("k1", 10, "zhangsan");
        jedis.zadd("k1", 20, "lisi");
        jedis.zadd("k1", 30, "wangwu");
        long size = jedis.zcard("k1");
        System.out.println("size: " + size);
        jedis.zrem("k1", "zhangsan", "lisi");
        size = jedis.zcard("k1");
        System.out.println("size: " + size);
    }
}
  1. 测试ZINTERSTORE命令:
/**
 * 测试ZINTERSTORE命令
 */
@Test
public void testZINTERSTORE() {
    // 1. 获取Jedis连接对象
    try (Jedis jedis = pool.getResource();) {
        // 设置密码(如果有的话)
        // jedis.auth("xxxxxx");
        // 2. 清空数据库
        jedis.flushDB();
        // 3. 测试ZINTERSTORE命令
        jedis.zadd("k1", 10, "zhangsan");
        jedis.zadd("k2", 20, "zhangsan");
        jedis.zinterstore("k3", "k1", "k2");
        List<Tuple> tuples = jedis.zrangeWithScores("k3", 0, -1);
        System.out.println("tuples: " + tuples);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值