Redis指令

Redis命令

1.Redis启动命令

1.Linux启动Redis服务器

#在备份的配置文件下启动redis服务器
$ redis-server backupconfig/redis.conf

2.连接Redis服务器

#连接到主机为 host,端口为 port ,密码为 mypass 的 redis 服务上
$ redis-cli -h host -p port -a password
#连接到主机为 127.0.0.1,端口为 6379
$ redis-cli -h 127.0.0.1 -p 6379
#解决有时候会有中文乱码
$ redis-cli --raw

2.五大基本类型

1.Redis 键(key)

#该命令用于在 key 存在时删除 key
$ del key
#序列化给定 key ,并返回被序列化的值
$ dump key
#检查给定 key 是否存在
$ exists key
-------设置过期时间-------
#为给定 key 设置过期时间,以秒计
$ expire key seconds
#设置 key 的过期时间,以毫秒计
$ pexpire key milliseconds
------------------------
#查找所有符合给定模式( pattern)的 key,例如:Keys * 、Keys *a*
$ keys pattern
#将当前数据库的 key 移动到给定的数据库 db 当中
$ move key index
#移除 key 的过期时间,key 将持久保持
$ persist key
-------查看剩余过期时间-------
#以毫秒为单位返回 key 的剩余的过期时间
$ ttl key
#以秒为单位,返回给定 key 的剩余生存时间
$ pttl key
----------------------------
#从当前数据库中随机返回一个 key
$ randomkey
#修改 key 的名称
$ rename key newName
#返回 key 所储存的值的类型
$ type key

2.Redis 字符串(String)

#设置指定 key 的值
$ set key
#获取指定 key 的值
$ get key
#存在该key就给该key赋值value并返回原先的value,否则不操作
$ getset key value
#获取所有(一个或多个)给定 key 的值
$ mget [key1 key2 ..]
#返回 key 中字符串值的子字符,start、end为对应字符串字符下标
$ getrange key start end
#注意:getrange key 0 -1 表示获取整个字符串,0表示第一个,-1表示最后一个
-----------重点-------------
#将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)
$ setex key milliseconds value
#将值 value 关联到 key ,并设置key 的过期时间(以毫秒为单位)
$ psetex key seconds value
#只有在 key 不存在时设置 key 的值
$ setnx key value
-------同时设置多个值----------
#设置一个或多个 key-value 的值
$ mset key1 value1 [key2 value2...]
#同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在
$ msetnx key1 value1 [key2 value2...]
----------------------------
#返回 key 所储存的字符串值的长度
$ strlen key
#将 key 中储存的数字值增一
$ incr key
#将 key 中储存的数字值减一
$ decr key
#将 key 所储存的值加上给定的增量值(increment) 
$ incr key increment
#key 所储存的值减去给定的减量值(decrement) 
$ decr key decrement
#key存在则将指定的value追加到该key原来值的末尾,不存在则创建一个值为value的key
$ append key value

3.Redis 列表(List)

key表示列表名称,值可重复,有序

--------------存值--------------
#将一个或多个值插入到列表头部(从左开始)
$ lpush key value1[value2...]
#将一个值插入到已存在的列表头部(从左开始)
$ lpshx key value 
#在列表尾部添加一个或多个值(从左开始)
$ rpush key value1[value2...]
#在列表尾部添加一个值(从左开始)
$ rpshx key value 
# 在列表的元素前或者后插入元素
# 注意:当列表中指定元素(pivot)存在多个时,会选择第一个元素作为参照(从左开始)
$ linsert key before|after pivot value
----------------查找-----------------
#获取列表长度
$ llen key
# 获取列表指定范围内的元素,start、end为对应列表对应下标
# lrange key 0 -1 可以获取整个列表的值,0表示第一个,-1表示最后一个
$ lrange key start end
# 通过索引获取列表中的元素(不会删除)
$ lindex key index
--------------移除---------------
#移出并获取列表的第一个元素,返回值为移除的元素
$ lpop key
#移除列表的最后一个元素,返回值为移除的元素(从左开始)
$ rpop key
#移出并获取列表的第一个元素并设置超时时间(秒)
#如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
$ blpop key1[key2] timeout
#移出并获取列表的最后一个元素并设置超时时间(秒)
#如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
$ rlpop key1[key2] timeout
#移除一个或多个(count)列表中值为value的元素(从左开始)
$ lrem key count value
# 移除列表的最后一个元素,并将该元素添加到另一个列表(或自身列表)第一个元素并返回
$ rpushlpop resource destinatio
----------------其他------------------
#通过索引设置列表元素的值(只能设置列表存在的值,类似于update操作)
$ lset key index value
#让列表只保留指定区间(start-stop)内的元素,不在指定区间之内的元素都将被删除
$ ltrim key start stop

4.Redis 集合(Set)

key表示set集合,元素不可重复,无序,member为集合元素

--------------存值-----------------
#向集合添加一个或多个成员
$ sadd key member1 [member2...]
--------------查看-----------------
# 返回集合中的所有成员
$ smembers key
#返回集合中一个或多个随机元素
$ srandmember key count
#获取集合的成员数
$ scard key
-------------移除-------------------
#移除集合中一个或多个成员
$ srem key member [member1...]
#移除并返回集合中的一个或多个随机元素
$ spop key [count]
--------------差交并集------------------
#返回第一个集合与其他集合之间的差集
$ sdiff key1 [key2...]
#返回第一个集合与所有集合的差集并存储在destination中
$ sdiffstore destination key key1 [key2...]
#返回给定所有集合的交集
$ sinter key key1 [key2...]
#返回给定所有集合的交集并存储在 destination 中
$ sinterstore destination key key1 [key2...]
#返回所有给定集合的并集
$ sunion key key1 [key2...]
#所有给定集合的并集存储在 destination 集合中
$ sunionstore destination key key1 [key2...]
-------------其他---------------------
#判断 member 元素是否是集合 key 的成员
$ sismember key member
#将一个元素(member)从source集合移动到destination集合
$ smove source destination member

5.Redis 哈希(Hash)

key表示hash表,field-value表示一对键值对,同一hash表中键值对不可重复

--------------存值-----------------
#将哈希表 key 中的字段 field 的值设为 value
$ hset key field value
#同时将多个 field-value (域-值)对设置到哈希表 key 中
$ hmset key field1 value1 [field2 value2 ]
#只有在字段 field 不存在时,设置哈希表字段的值
$ hsetnx key field value
--------------取值-----------------
#获取存储在哈希表中指定字段的值
$ hget key field
#获取所有给定字段的值
$ hmget key field1 [field2..]
#获取所有哈希表中的字段
$ hkeys key
#获取在哈希表中指定 key 的所有字段和值
$ hgetall key
#获取哈希表中所有值
$ hvals key
# 获取哈希表中字段的数量
$ hlen key
#查看哈希表 key 中,指定的字段是否存在
$ hexists key field
--------------移除-----------------
#删除一个或多个哈希表字段
$ hdel key field1 [field2...]
----------------其他---------------
#为哈希表 key 中的指定字段的整数值加上增量 increment (increment可以为负数,表示减少)
$ hincrby key field increment

6.Redis 有序集合(Zset)

与set类似,元素不可重复,只是由无序变为有序,可以通过索引操纵元素,member为集合元素

------------------存值-------------------
# 向有序集合添加一个或多个成员,或者更新已存在成员的分数
$ zadd key score1 member1 [score2 member2]
------------------取值(查询)-------------------
#获取有序集合的成员数
$ zcard key
#计算在有序集合中指定区间分数的成员数(min为分数最小值范围,max为分数最大值范围)
$ zcount key min max
#在有序集合中计算指定字典区间内成员数量
$ zlexcount key min max
#通过索引区间返回有序集合指定区间内的成员 
#查询所有元素可以使用 zrange key 0 -1
$ zrange key start end 
#通过索引区间倒序返回有序集合指定区间内的成员 
#倒序查询所有元素可以使用 zrevrange key 0 -1
$ zrevrange key start end

#返回有序集中指定区间内的成员,通过索引,分数从高到低 -inf:负无穷,+inf:正无穷 
#按分数高低查询所有元素可以用:zrevrangebyscore myzset +inf -inf
$ zrevrangebyscore key max min
#按分数高低查询所有元素可以用:zrevrangebyscore myzset -inf +inf
#返回有序集中指定分数区间内的成员,分数从高到低排序
$ zrangebyscore key min max

#通过字典区间返回有序集合的成员
#按a-d顺序查询有序集合的成员可以用 zrangebylex myzset [a [d
#查询所有成员可以使用 zrangebylex key - + 或者 zrangebylex key a z
$ zrangebylex key min max
$ zrevrangebylex key max min

#返回有序集合中指定成员的索引(0开始)
$ zrank key member
#返回有序集合中指定成员的排名(0开始),有序集成员按分数值递减(从大到小)排序
$ zrevrank key member
#返回有序集中,成员的分数值
$ zscore key member
--------------移除------------------
#移除有序集合中的一个或多个成员
$ zrem key member [membe...]
#移除有序集合中给定的分数区间的所有成员
$ zremrangebyscore key min max
#移除有序集合中给定的排名区间的所有成员
$ zremrangebyrank key start stop
#移除有序集合中给定的字典区间的所有成员
$ zremrangebylex key start stop
-------------------交并集-------------
#计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合destination中,keycounts表示取交集的集合数量
$ zinterdestination destination keycounts key key1 [key2...]
#计算给定的一个或多个有序集的并集,并存储在新的 key 中,keycounts表示取交集的集合数量
$ zuniondestination destination keycounts key key1 [key2...]

3.三种特殊数据类型

1.Redis GEO

geoadd

​ geoadd 用于存储指定的地理空间位置,可以将一个或多个经度(longitude)、纬度(latitude)、位置名称(member)添加到指定的 key 中。

$ geoadd china:city 115.89 28.68 nanchang #江西南昌
$ geoadd china:city 115.7 28.19 fengcheng #江西丰城 
$ geoadd china:city 118.1 24.46 xiamen #福建厦门
$ geoadd china:city 119.3 26.08 fuzhou #福建福州
$ geoadd china:city 121.48 31.22 shanghai #上海

geopos

geopos 用于从给定的 key 里返回所有指定名称(member)的位置(经度和纬度),不存在的返回 nil。

$ GEOPOS china:city shanghai xiamen

geodist

​ geodist 用于返回两个给定位置之间的距离。

$ GEODIST key member1 member2 [m|km|ft|mi]
#厦门距上海直线距离
$ GEODIST china:city xiamen nanchang km
#821.9527
#厦门距丰城直线距离
$ GEODIST china:city xiamen fengcheng km
# 475.4369
  • m :米,默认单位。
  • km :千米。
  • mi :英里。
  • ft :英尺。

georadius、georadiusbymember

​ georadius 以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。

​ georadiusbymember 和 georadius 命令一样, 都可以找出位于指定范围内的元素, 但是 georadiusbymember 的中心点是由给定的 位置元素决定的, 而不是使用经度和纬度来决定中心点

$ GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
#以经纬度为110 28为中心 距离为1000km的城市
$ GEORADIUS china:city 110 28 1000 km
#xiamen
#fuzhou
#fengcheng
#nanchang
$ GEORADIUS china:city 110 28 1000 km whitdist  #显示距离
$ GEORADIUS china:city 110 28 1000 km WITHCOORD #显示经纬度
$ GEORADIUS china:city 110 28 1000 km whitdist desc  #由远到近,距离递减(默认)
$ GEORADIUS china:city 110 28 1000 km whitdist asc #由近到远,距离递增

$ GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
#以南昌为中心 距离为1000km的城市
$ GEORADIUSBYMEMBER china:city nanchang 100 km
#fengcheng
#nanchang

geohash

​ geohash 用于获取一个或多个位置元素的 geohash 值。

$ GEOHASH key member [member ...]
#获取地址的hash值
$ GEOHASH china:city nanchang
#wt47jjh90e0

2.Redis HyperLogLog

HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

什么是基数?

比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。

PFADD

#添加一个或多个元素到 HyperLogLog 中
$ pfadd key element1 [element2...]

PFCOUNT

#返回给定 HyperLogLog 的基数估算值。
$ pfcount key
#返回多个HyperLogLog并集的基数估算值
$ pfcount key1 key2 [key3...]

PFMERGE

#将多个 HyperLogLog 合并为一个 HyperLogLog
$	PFMERGE destkey sourcekey [sourcekey ...]

3.Bitmaps

SETBIT

​ 对 key所储存的字符串值,设置或清除指定偏移量上的位(bit)。

$ SETBIT key offset value
#offset参数必须大于或等于0,小于 2^32 (bit 映射被限制在 512 MB 之内)
# value 0或1
$ SETBIT bit 0 1
0 			#返回值表示原来位上的值
$ SETBIT bit 0 1
1				#返回值表示原来位上的值

GETBIT

​ 对 key所储存的字符串值,获取指定偏移量上的位(bit)。

$ GETBIT key offset
# bit 1001
$ GETBIT bit 0
1
$ GETBIT bit 1
0
$ GETBIT bit 2
0
$ GETBIT bit 3
1

BITCOUNT

计算给定字符串中,被设置为 1 的比特位的数量。

1 byte (字节)= 8 bit(位)
1 int = 4byte = 4*8 bit =32 bit
1 KB = 1024 B(字节)
1 MB = 1024 KB; (2^10 B)
1 GB = 1024 MB; (2^20 B)
1 TB = 1024 GB; (2^30 B)
一般 utf-8 编码下,一个汉字 字符 占用 3 个 字节
一般 gbk 编码下,一个汉字 字符 占用 2 个 字节

注意:redis的setbit设置或清除的是bit位置,而bitcount计算的是byte位置,1byte=8bit。

#start 和 end 参数的设置和 GETRANGE 命令类似,都可以使用负数值:比如 -1 表示最后一个字节,而 -2 表示倒数第二个字节,以此类推。
$ BITCOUNT key [start end]
#例如我分别在ofset为 10 和 17 的位置上设置 1 
$ setbit key 10 1
$ setbit key 17 1
#计算 key 被设置为 1 的比特位的数量
$ bitcount key
2
#若指定区间,则需要先计算出位所对应的byte的位置,如 10/8= 1...2说明就在第二个字节,对应index=1 (0开始),同理 17对应在第三字节,index=2,所有可以通过:
$ bitcount key 1 2 
2
#找到 10 和 17并计算count

**拓展:BitMap 40亿数据处理题目 **

给你一个文件,里面包含40亿个整数,如何利用bitMap思想找出该文件中不包含的一个整数, 假设你有1GB内存可用。

 我们用1Byte代替一个整数,那40亿数据大概要40*10^8*bit = 0.5GB,满足内存要求。
 用int来表示:Int  bmap[1+sum/32]; //N是总数,sum=40*(10^8),一个int=32Bit=4Byte
 然后我们插入一个整数ze,要先计算整数ze位于数组Bitmap中的索引:index = ze/32;(除以32是得到整数位于第几个Byte,也就是第几位)
 比如整数35,index=35/32=1, 35%32=3(取余) 第35位于数组中的index=1(位于数组BitMap[1]中标识等于3的位置),然后就是标识 这个位置为1。
 知道了这些,我们就可以检测哪个整数不在数据里面了。
 如:检测35,先计算index,在数组BitMap的标识位置
 35: index = 1, 在BitMap[1]中的位置为 1,只需要检测这个位置是否为1
 BitMap[1] &(1<<1),这样是1返回true,否侧返回false 

BITPOS

​ 返回位图中第一个值为指定 bit 的二进制位的位置。在默认情况下, 命令将检测整个位图, 但用户也可以通过可选的 start 参数和 end 参数指定要检测的范围。

​ 注意:start 参数和 end 参数是byte位置,1byte=8bit。

#返回位图中第一个值为指定 bit 的二进制位的位置
$ BITPOS key bit [start end]
#例如我分别在ofset为 10 和 17 的位置上设置 1 
$ setbit key 10 1
$ setbit key 17 1
#若指定区间找出第一个值为1的二进制位置,则需要先计算出位所对应的byte的位置,如 10/8= 1...2说明就在第二个字节,对应index=1 (0开始),同理 17对应在第三字节,index=2,所有可以通过:
$ BITPOS key 1 1 2
10

BITOP

​ 对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上,operation 可以是 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种.

位运算

符号 描述 运算规则
& 与 两个位都为1时,结果才为1
| 或 两个位都为0时,结果才为0
^ 异或 两个位相同为0,相异为1
~ 取反 0变1,1变0
<< 左移 各二进位全部左移若干位,高位丢弃,低位补0
>> 右移 各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)
$ BITOP operation destkey key [key …]
#对一个或多个 key 求逻辑并,并将结果保存到 destkey   (两个位都为1时,结果才为1)
$ BITOP AND destkey key [key ...]
#对一个或多个 key 求逻辑或,并将结果保存到 destkey   (两个位都为0时,结果才为0)
$ BITOP OR destkey key [key ...]
#对一个或多个 key 求逻辑异或,并将结果保存到 destkey  (两个位相同为0,相异为1)
$ BITOP XOR destkey key [key ...]
#对一个或多个 key 求逻辑异或,并将结果保存到 destkey   (0变1,1变0)
$ BITOP NOT destkey key

4.事务

Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:

  • 批量操作在发送 EXEC 命令前被放入队列缓存。
  • 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
  • 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。

以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令

#开始事务
$ MULTI
...
#事务块
...
#取消事务,放弃执行事务块内的所有命令
$ DISCARD
#执行所有事务块内的命令。
$ EXEC

单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。

#倘若发生运行时错误(如对字符串使用incr命令),但是这并不影响其他指令的执行
  127.0.0.1:6379> MULTI
  OK
  127.0.0.1:6379> set a aaa
  QUEUED
  127.0.0.1:6379> incr a
  QUEUED
  127.0.0.1:6379> set b bbb
  QUEUED
  127.0.0.1:6379> EXEC
  OK
  ERR value is not an integer or out of range
  OK
  127.0.0.1:6379> get a
  aaa
  127.0.0.1:6379> get b
  bbb
#倘若在set b bbb出发生指令错误,那么其他指令也不会被执行
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set a aaa
QUEUED
127.0.0.1:6379> set 
ERR wrong number of arguments for 'set' command
127.0.0.1:6379> set b bbb
QUEUED
127.0.0.1:6379> EXEC
EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get a
nil
127.0.0.1:6379> get b
nil

5.乐观锁

#监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断
$ WATCH key [key ...]
#取消 WATCH 命令对所有 key 的监视
$ UNWATCH
#例如现在在创建事务之前通过watch监视某个key(类似加锁)
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> WATCH money
OK
#创建事务并对money进行修改
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> INCR money
QUEUED
#同时通过另一客户端对money进行修改,m
127.0.0.1:6379> set money 10000
OK
#发现事务执行失败
127.0.0.1:6379> EXEC
nil

6.Jedis

在java程序中可以通过Jedis对象来连接Redis服务器,并且通过jedis来操作Redis服务器。

1.导入依赖

<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.3.0</version>
</dependency>

2.创建jedis对象

#Jedis构造
public Jedis(String host, int port) {
        super(host, port);
    }
#创建jedis对象
Jedis jedis = new Jedis("localhost",6379);

3.resdis模板工具类

public class RedisUtils {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private final String DEFAULT_KEY_PREFIX = "";
    private final int EXPIRE_TIME = 1;
    private final TimeUnit EXPIRE_TIME_TYPE = TimeUnit.DAYS;


    /**
     * 数据缓存至redis
     *
     * @param key
     * @param value
     * @return
     */
    public <K, V> void add(K key, V value) {
        try {
            if (value != null) {
                redisTemplate
                        .opsForValue()
                        .set(DEFAULT_KEY_PREFIX + key, JSON.toJSONString(value));
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("数据缓存至redis失败");
        }
    }

    /**
     * 数据缓存至redis并设置过期时间
     *
     * @param key
     * @param value
     * @return
     */
    public <K, V> void add(K key, V value, long timeout, TimeUnit unit) {
        try {
            if (value != null) {
                redisTemplate
                        .opsForValue()
                        .set(DEFAULT_KEY_PREFIX + key, JSON.toJSONString(value), timeout, unit);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("数据缓存至redis失败");
        }
    }

    /**
     * 写入 hash-set,已经是key-value的键值,不能再写入为hash-set
     *
     * @param key    must not be {@literal null}.
     * @param subKey must not be {@literal null}.
     * @param value  写入的值
     */
    public <K, SK, V> void addHashCache(K key, SK subKey, V value) {
        redisTemplate.opsForHash().put(DEFAULT_KEY_PREFIX + key, subKey, value);
    }

    /**
     * 写入 hash-set,并设置过期时间
     *
     * @param key    must not be {@literal null}.
     * @param subKey must not be {@literal null}.
     * @param value  写入的值
     */
    public <K, SK, V> void addHashCache(K key, SK subKey, V value, long timeout, TimeUnit unit) {
        redisTemplate.opsForHash().put(DEFAULT_KEY_PREFIX + key, subKey, value);
        redisTemplate.expire(DEFAULT_KEY_PREFIX + key, timeout, unit);
    }

    /**
     * 获取 hash-setvalue
     *
     * @param key    must not be {@literal null}.
     * @param subKey must not be {@literal null}.
     */
    public <K, SK> Object getHashCache(K key, SK subKey) {
        return  redisTemplate.opsForHash().get(DEFAULT_KEY_PREFIX + key, subKey);
    }


    /**
     * 从redis中获取缓存数据,转成对象
     *
     * @param key   must not be {@literal null}.
     * @param clazz 对象类型
     * @return
     */
    public <K, V> V getObject(K key, Class<V> clazz) {
        String value = this.get(key);
        V result = null;
        if (!StringUtils.isEmpty(value)) {
            result = JSONObject.parseObject(value, clazz);
        }
        return result;
    }

    /**
     * 从redis中获取缓存数据,转成list
     *
     * @param key   must not be {@literal null}.
     * @param clazz 对象类型
     * @return
     */
    public <K, V> List<V> getList(K key, Class<V> clazz) {
        String value = this.get(key);
        List<V> result = Collections.emptyList();
        if (!StringUtils.isEmpty(value)) {
            result = JSONArray.parseArray(value, clazz);
        }
        return result;
    }

    /**
     * 功能描述:Get the value of {@code key}.
     *
     * @param key must not be {@literal null}.
     * @return java.lang.String
     * @date 2021/9/19
     **/
    public <K> String get(K key) {
        String value;
        try {
            value = redisTemplate.opsForValue().get(DEFAULT_KEY_PREFIX + key);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("从redis缓存中获取缓存数据失败");
        }
        return value;
    }

    /**
     * 删除key
     */
    public void delete(String key) {
        redisTemplate.delete(key);
    }

    /**
     * 批量删除key
     */
    public void delete(Collection<String> keys) {
        redisTemplate.delete(keys);
    }

    /**
     * 序列化key
     */
    public byte[] dump(String key) {
        return redisTemplate.dump(key);
    }

    /**
     * 是否存在key
     */
    public Boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 设置过期时间
     */
    public Boolean expire(String key, long timeout, TimeUnit unit) {
        return redisTemplate.expire(key, timeout, unit);
    }

    /**
     * 设置过期时间
     */
    public Boolean expireAt(String key, Date date) {
        return redisTemplate.expireAt(key, date);
    }


    /**
     * 移除 key 的过期时间,key 将持久保持
     */
    public Boolean persist(String key) {
        return redisTemplate.persist(key);
    }

    /**
     * 返回 key 的剩余的过期时间
     */
    public Long getExpire(String key, TimeUnit unit) {
        return redisTemplate.getExpire(key, unit);
    }

    /**
     * 返回 key 的剩余的过期时间
     */
    public Long getExpire(String key) {
        return redisTemplate.getExpire(key);
    }

    /**
     * 往队列的左侧插入值
     */
    public <K, V> void lPush(K key, V value){
        try {
            if (value != null){
                redisTemplate.opsForList().leftPush(DEFAULT_KEY_PREFIX + key , JSON.toJSONString(value)) ;
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("往队列的左侧插入值失败");
        }

    }

    /**
     * 从队列的右侧取值
     */
    public <K, V> V rPop(K key, Class<V> clazz){

        try {
            String rightPop = redisTemplate.opsForList().rightPop(DEFAULT_KEY_PREFIX + key);
            V result = null;
            if (!StringUtils.isEmpty(rightPop)) {
                result = JSONObject.parseObject(rightPop, clazz);
            }
            return result;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("从队列的右侧取值失败");
        }

    }

}

posted @ 2021-04-26 20:22  一只小周皮妖🐯  阅读(123)  评论(0)    收藏  举报