目录
- 1、redis介绍
- 2、redis五种数据类型
- 2.1 String(字符串)
- 2.2 List(列表)
- 2.3 Set(集合)元素唯一不重复
- 2.3 Hash(哈希)
- 2.4 zSet(有序集合)
- 3、SpringBoot整合Redis
- 3.1 项目框架
- 3.2 项目配置
- 3.2.1 项目依赖
- 3.2.2 配置文件
- 3.3 使用redis
- 3.4 测试结果
1、redis介绍
redis是一个开源的、使用C语言编写的、支持网络交互的、可基于内存也可持久化的Key-Value数据库
2、redis五种数据类型
2.1 String(字符串)
①添加、查询、追加、获取长度,判断是否存在的操作
127.0.0.1:6379> set name dingdada #插入一个key为‘name’值为‘dingdada’的数据
OK
127.0.0.1:6379> get name #获取key为‘name’的数据
"dingdada"
②自增、自减操作
127.0.0.1:6379> set num 0 #插入一个初始值为0的数据
OK
127.0.0.1:6379> get num
"0"
127.0.0.1:6379> incr num #指定key为‘num’的数据自增1,返回结果 相当于java中 i++
(integer) 1
127.0.0.1:6379> get num #一般用来做文章浏览量、点赞数、收藏数等功能
"1"
127.0.0.1:6379> incr num
(integer) 2
127.0.0.1:6379> incr num
(integer) 3
127.0.0.1:6379> get num
"3"
127.0.0.1:6379> decr num #指定key为‘num’的数据自减1,返回结果 相当于java中 i--
(integer) 2
③截取、替换字符串操作
#截取
127.0.0.1:6379> set key1 "hello world!"
OK
127.0.0.1:6379> get key1
"hello world!"
127.0.0.1:6379> GETRANGE key1 0 4 #截取字符串,相当于java中的subString,下标从0开始,不会改变原有数据
"hello"
127.0.0.1:6379> get key1
"hello world!"
127.0.0.1:6379> GETRANGE key1 0 -1 #0至-1相当于 get key1,效果一致,获取整条数据
"hello world!"
#替换
127.0.0.1:6379> set key2 "hello,,,world!"
OK
127.0.0.1:6379> get key2
"hello,,,world!"
④设置过期时间、不存在设置操作
#设置过期时间,跟Expire的区别是前者设置已存在的key的过期时间,而setex是在创建的时候设置过期时间
127.0.0.1:6379> setex name1 15 dingdada #新建一个key为‘name1’,值为‘dingdada’,过期时间为15秒的字符串数据
OK
127.0.0.1:6379> ttl name1 #查看key为‘name1’的key的过期时间
(integer) 6
127.0.0.1:6379> ttl name1
(integer) 5
127.0.0.1:6379> ttl name1
(integer) 3
127.0.0.1:6379> ttl name1
(integer) 1
127.0.0.1:6379> ttl name1
(integer) 0
127.0.0.1:6379> ttl name1 #返回为-2时证明该key已过期,即不存在
(integer) -2
⑤mset、mget操作
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 #插入多条数据
OK
127.0.0.1:6379> keys * #查询所有数据
1) "k2"
2) "k3"
3) "k1"
127.0.0.1:6379> mget k1 k2 k3 #查询key为‘k1’,‘k2’,‘k3’的数据
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> MSETNX k1 v1 k4 v4 #msetnx是一个原子性的操作,在一定程度上保证了事务!要么都成功,要么都失败!相当于if中的条件&&(与)
(integer) 0
127.0.0.1:6379> keys *
1) "k2"
2) "k3"
3) "k1"
127.0.0.1:6379> MSETNX k5 v5 k4 v4 #全部成功
(integer) 1
127.0.0.1:6379> keys *
1) "k2"
2) "k4"
3) "k3"
4) "k5"
5) "k1"
⑥添加获取对象、getset操作
#这里其实本质上还是字符串,但是我们讲其key巧妙的设计了一下。
##mset student:1:name student 相当于类名,1 相当于id,name 相当于属性
#如果所需数据全部这样设计,那么我们在java的业务代码中,就不需要关注太多的key
#只需要找到student类,下面哪个id,需要哪个属性即可,减少了代码的繁琐,在一定程度上可以理解为这个一个类的对象!
127.0.0.1:6379> mset student:1:name dingdada student:1:age 22 #新增一个key为‘student:1:name’,value为‘dingdada ’。。等数据
OK
127.0.0.1:6379> keys * #查看所有的key
1) "student:1:age"
2) "student:1:name"
127.0.0.1:6379> mget student:1:age student:1:name #获取数据
1) "22"
2) "dingdada"
##getset操作
127.0.0.1:6379> getset name1 dingdada1 #先get再set,先获取key,如果没有,set值进去,返回的是get的值
(nil)
127.0.0.1:6379> get name1
"dingdada1"
127.0.0.1:6379> getset name1 dingdada2 ##先获取key,如果有,set(替换)最新的值进去,返回的是get的值
"dingdada1"
127.0.0.1:6379> get name1 #替换成功
"dingdada2"
2.2 List(列表)
①lpush(左插入)、lrange(查询集合)、rpush(右插入)操作
#lpush
127.0.0.1:6379> lpush list v1 #新增一个集合
(integer) 1
127.0.0.1:6379> lpush list v2
(integer) 2
127.0.0.1:6379> lpush list v3
(integer) 3
#lrange
127.0.0.1:6379> LRANGE list 0 -1 #查询list的所有元素值
1) "v3"
2) "v2"
3) "v1"
127.0.0.1:6379> lpush list1 v1 v2 v3 v4 v5 #批量添加集合元素
(integer) 5
127.0.0.1:6379> LRANGE list1 0 -1
1) "v5"
2) "v4"
3) "v3"
4) "v2"
5) "v1"
###这里大家有没有注意到,先进去的会到后面,也就是我们的lpush的意思是左插入,l--left
#rpush
127.0.0.1:6379> LRANGE list 0 1 #指定查询列表中的元素,从下标零开始,1结束,两个元素
1) "v3"
2) "v2"
127.0.0.1:6379> LRANGE list 0 0 #指定查询列表中的唯一元素
1) "v3"
127.0.0.1:6379> rpush list rv0 #右插入,跟lpush相反,这里添加进去元素是在尾部!
(integer) 4
127.0.0.1:6379> lrange list 0 -1 #查看集合所有元素
1) "v3"
2) "v2"
3) "v1"
4) "rv0"
##联想:这里我们是不是可以做一个,保存的记录值(如:账号密码的记录),
每次都使用lpush,老的数据永远在后面,我们每次获取 0 0 位置的元素,是不是相当于更新了
数据操作,但是数据记录还在?想要查询记录即可获取集合所有元素!
②lpop(左移除)、rpop(右移除)操作
#lpop
127.0.0.1:6379> LRANGE list 0 -1
1) "v5"
2) "v4"
3) "v3"
4) "v2"
5) "v1"
127.0.0.1:6379> lpop list #从头部开始移除第一个元素
"v5"
##################
#rpop
127.0.0.1:6379> LRANGE list 0 -1
1) "v4"
2) "v3"
3) "v2"
4) "v1"
127.0.0.1:6379> rpop list
"v1"
127.0.0.1:6379> LRANGE list 0 -1 #从尾部开始移除第一个元素
1) "v4"
2) "v3"
3) "v2"
③lindex(查询指定下标元素)、llen(获取集合长度) 操作
#lindex
127.0.0.1:6379> LRANGE list 0 -1
1) "v4"
2) "v3"
3) "v2"
127.0.0.1:6379> lindex list 1 #获取指定下标位置集合的元素,下标从0开始计数
"v3"
127.0.0.1:6379> lindex list 0 #相当于java中的indexof
"v4"
#llen
127.0.0.1:6379> llen list #获取指定集合的元素长度,相当于java中的length或者size
(integer) 3
④lrem(根据value移除指定的值)
127.0.0.1:6379> LRANGE list 0 -1
1) "v4"
2) "v3"
3) "v2"
127.0.0.1:6379> lrem list 1 v2 #移除集合list中的元素是v2的元素1个
(integer) 1
127.0.0.1:6379> LRANGE list 0 -1
1) "v4"
2) "v3"
127.0.0.1:6379> lrem list 0 v3 #移除集合list中的元素是v2的元素1个,这里的0和1效果是一致的
(integer) 1
127.0.0.1:6379> LRANGE list 0 -1
1) "v4"
127.0.0.1:6379> lpush list v3 v2 v2 v2
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "v2"
2) "v2"
3) "v2"
4) "v3"
5) "v4"
127.0.0.1:6379> lrem list 3 v2 #移除集合list中元素为v2 的‘3’个,这里的参数数量,如果实际中集合元素数量不达标,不会报错,全部移除后返回成功移除后的数量值
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1
1) "v3"
2) "v4"
⑥ltrim(截取元素)、rpoplpush(移除指定集合中最后一个元素到一个新的集合中)操作
#ltrim
127.0.0.1:6379> lpush list v1 v2 v3 v4
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "v4"
2) "v3"
3) "v2"
4) "v1"
127.0.0.1:6379> ltrim list 1 2 #通过下标截取指定的长度,这个list已经被改变了,只剩下我们所指定截取后的元素
OK
127.0.0.1:6379> LRANGE list 0 -1
1) "v3"
2) "v2"
################
#rpoplpush
127.0.0.1:6379> lpush list v1 v2 v3 v4 v5
(integer) 5
127.0.0.1:6379> LRANGE list 0 -1
1) "v5"
2) "v4"
3) "v3"
4) "v2"
5) "v1"
127.0.0.1:6379> rpoplpush list newlist #移除list集合中的最后一个元素到新的集合newlist中,返回值是移除的最后一个元素值
"v1"
127.0.0.1:6379> LRANGE list 0 -1
1) "v5"
2) "v4"
3) "v3"
4) "v2"
127.0.0.1:6379> LRANGE newlist 0 -1 #确实存在该newlist集合并且有刚刚移除的元素,证明成功
1) "v1"
⑦lset(更新)、linsert操作
#lset
127.0.0.1:6379> LRANGE list 0 -1
1) "v5"
2) "v4"
3) "v3"
4) "v2"
127.0.0.1:6379>
127.0.0.1:6379> lset list 1 newV5 #更新list集合中下标为‘1’的元素为‘newV5’
OK
127.0.0.1:6379> LRANGE list 0 -1 #查看证明更新成功
1) "v5"
2) "newV5"
3) "v3"
4) "v2"
##注意点:
127.0.0.1:6379> lset list1 0 vvvv #如果指定的‘集合’不存在,报错
(error) ERR no such key
127.0.0.1:6379> lset list 8 vvv #如果集合存在,但是指定的‘下标’不存在,报错
(error) ERR index out of range
########################
#linsert
127.0.0.1:6379> LRANGE list 0 -1
1) "v5"
2) "newV5"
3) "v3"
4) "v2"
127.0.0.1:6379> LINSERT list after v3 insertv3 #在集合中的‘v3’元素 ‘(after)之后’ 加上一个元素
(integer) 5
127.0.0.1:6379> LRANGE list 0 -1
1) "v5"
2) "newV5"
3) "v3"
4) "insertv3"
5) "v2"
127.0.0.1:6379> LINSERT list before v3 insertv3 #在集合中的‘v3’元素 ‘(before)之前’ 加上一个元素
(integer) 6
127.0.0.1:6379> LRANGE list 0 -1
1) "v5"
2) "newV5"
3) "insertv3"
4) "v3"
5) "insertv3"
6) "v2"
⑧小结:
实际上是一个链表,before Node after , left,right 都可以插入值
如果key 不存在,创建新的链表
如果key存在,新增内容
如果移除了所有值,空链表,也代表不存在!
在两边插入或者改动值,效率最高! 中间元素,相对来说效率会低一点~
消息排队!消息队列 (Lpush Rpop), 栈( Lpush Lpop)!
2.3 Set(集合)元素唯一不重复
①sadd(添加)、smembers(查看所有元素)、sismember(判断是否存在)、scard(查看长度)、srem(移除指定元素)操作
#set中所有的元素都是唯一的不重复的!
127.0.0.1:6379> sadd set1 ding da mian tiao #添加set集合(可批量可单个,写法一致,不再赘述)
(integer) 4
127.0.0.1:6379> SMEMBERS set1 #查看set中所有元素
1) "mian"
2) "da"
3) "tiao"
4) "ding"
127.0.0.1:6379> SISMEMBER set1 da #判断某个值在不在set中,在返回1
(integer) 1
127.0.0.1:6379> SISMEMBER set1 da1 #不在返回0
(integer) 0
127.0.0.1:6379> SCARD set1 #查看集合的长度,相当于size、length
(integer) 4
127.0.0.1:6379> srem set1 da #移除set中指定的元素
(integer) 1
127.0.0.1:6379> SMEMBERS set1 #移除成功
1) "mian"
2) "tiao"
3) "ding"
②srandmember(抽随机)操作
127.0.0.1:6379> sadd myset 1 2 3 4 5 6 7 #在set中添加7个元素
(integer) 7
127.0.0.1:6379> SMEMBERS myset
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"
127.0.0.1:6379> SRANDMEMBER myset 1 #随机抽取myset中1个元素返回
1) "4"
127.0.0.1:6379> SRANDMEMBER myset 1 #随机抽取myset中1个元素返回
1) "1"
127.0.0.1:6379> SRANDMEMBER myset 1 #随机抽取myset中1个元素返回
1) "5"
127.0.0.1:6379> SRANDMEMBER myset #不填后参数,默认抽1个值,但是下面返回不会带序号值
"3"
127.0.0.1:6379> SRANDMEMBER myset 3 #随机抽取myset中3个元素返回
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> SRANDMEMBER myset 3 #随机抽取myset中3个元素返回
1) "6"
2) "3"
3) "5"
③spop(随机删除元素)、smove(移动指定元素到新的集合中)操作
127.0.0.1:6379> SMEMBERS myset
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"
127.0.0.1:6379> spop myset #随机删除1个元素,不指定参数值即删除1个
"2"
127.0.0.1:6379> spop myset 1 #随机删除1个元素
1) "7"
127.0.0.1:6379> spop myset 2 #随机删除2个元素
1) "3"
2) "5"
127.0.0.1:6379> SMEMBERS myset #查询删除后的结果
1) "1"
2) "4"
3) "6"
127.0.0.1:6379> smove myset myset2 1 #移动指定set中的指定元素到新的set中
(integer) 1
127.0.0.1:6379> SMEMBERS myset #查询原来的set集合
1) "4"
2) "6"
127.0.0.1:6379> SMEMBERS myset2 #查询新的set集合,如果新的set存在,即往后加,如果不存在,则自动创建set并且加入进去
1) "1"
④sdiff(差集)、sinter(交集)、sunion(并集)操作
127.0.0.1:6379> sadd myset1 1 2 3 4 5
(integer) 5
127.0.0.1:6379> sadd myset2 3 4 5 6 7
(integer) 5
127.0.0.1:6379> SMEMBERS myset1
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
127.0.0.1:6379> SMEMBERS myset2
1) "3"
2) "4"
3) "5"
4) "6"
5) "7"
127.0.0.1:6379> SDIFF myset1 myset2 #查询指定的set之间的差集,可以是多个set
1) "1"
2) "2"
127.0.0.1:6379> SINTER myset1 myset2 #查询指定的set之间的交集,可以是多个set
1) "3"
2) "4"
3) "5"
127.0.0.1:6379> sunion myset1 myset2 #查询指定的set之间的并集,可以是多个set
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"
⑤总结:可实现共同好友、共同关注等需求。
2.3 Hash(哈希)
①hset(添加hash)、hget(查询)、hgetall(查询所有)、hdel(删除hash中指定的值)、hlen(获取hash的长度)、hexists(判断key是否存在)操作
127.0.0.1:6379> hset myhash name dingdada age 23 #添加hash,可多个
(integer) 2
127.0.0.1:6379> hget myhash name #获取hash中key是name的值
"dingdada"
127.0.0.1:6379> hget myhash age #获取hash中key是age的值
"23"
127.0.0.1:6379> hgetall myhash #获取hash中所有的值,包含key
1) "name"
2) "dingdada"
3) "age"
4) "23"
127.0.0.1:6379> hset myhash del test #添加
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "name"
2) "dingdada"
3) "age"
4) "23"
5) "del"
6) "test"
127.0.0.1:6379> hdel myhash del age #删除指定hash中的key(可多个),key删除后对应的value也会被删除
(integer) 2
127.0.0.1:6379> hgetall myhash
1) "name"
2) "dingdada"
127.0.0.1:6379> hlen myhash #获取指定hash的长度,相当于length、size
(integer) 1
127.0.0.1:6379> HEXISTS myhash name #判断key是否存在于指定的hash,存在返回1
(integer) 1
127.0.0.1:6379> HEXISTS myhash age #判断key是否存在于指定的hash,不存在返回0
(integer) 0
②hkeys(获取所有key)、hvals(获取所有value)、hincrby(给值加增量)、hsetnx(存在不添加)操作
127.0.0.1:6379> hset myhash age 23 high 173
(integer) 2
127.0.0.1:6379> hgetall myhash
1) "name"
2) "dingdada"
3) "age"
4) "23"
5) "high"
6) "173"
127.0.0.1:6379> hkeys myhash #获取指定hash中的所有key
1) "name"
2) "age"
3) "high"
127.0.0.1:6379> hvals myhash #获取指定hash中的所有value
1) "dingdada"
2) "23"
3) "173"
127.0.0.1:6379> hincrby myhash age 2 #让hash中age的value指定+2(自增)
(integer) 25
127.0.0.1:6379> hincrby myhash age -1 #让hash中age的value指定-1(自减)
(integer) 24
127.0.0.1:6379> hsetnx myhash nokey novalue #添加不存在就新增返回新增成功的数量(只能单个增加哦)
(integer) 1
127.0.0.1:6379> hsetnx myhash name miaotiao #添加存在则失败返回0
(integer) 0
127.0.0.1:6379> hgetall myhash
1) "name"
2) "dingdada"
3) "age"
4) "24"
5) "high"
6) "173"
7) "nokey"
8) "novalue"
③总结:比String更加适合存对象~
2.4 zSet(有序集合)
①zadd(添加)、zrange(查询)、zrangebyscore(排序小-大)、zrevrange(排序大-小)、zrangebyscore withscores(查询所有值包含key)操作
127.0.0.1:6379> zadd myzset 1 one 2 two 3 three #添加zset值,可多个
(integer) 3
127.0.0.1:6379> ZRANGE myzset 0 -1 #查询所有的值
1) "one"
2) "two"
3) "three"
#-inf 负无穷 +inf 正无穷
127.0.0.1:6379> ZRANGEBYSCORE myzset -inf +inf #将zset的值根据key来从小到大排序并输出
1) "one"
2) "two"
3) "three"
127.0.0.1:6379> ZRANGEBYSCORE myzset 0 1 #只查询key<=1的值并且排序从小到大
1) "one"
127.0.0.1:6379> ZREVRANGE myzset 1 -1 #从大到小排序输出
1) "two"
2) "one"
127.0.0.1:6379> ZRANGEBYSCORE myzset -inf +inf withscores #查询指定zset的所有值,包含序号的值
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"
②zrem(移除元素)、zcard(查看元素个数)、zcount(查询指定区间内的元素个数)操作
127.0.0.1:6379> zadd myset 1 v1 2 v2 3 v3 4 v4
(integer) 4
127.0.0.1:6379> ZRANGE myset 0 -1
1) "v1"
2) "v2"
3) "v3"
4) "v4"
127.0.0.1:6379> zrem myset v3 #移除指定的元素,可多个
(integer) 1
127.0.0.1:6379> ZRANGE myset 0 -1
1) "v1"
2) "v2"
3) "v4"
127.0.0.1:6379> zcard myset #查看zset的元素个数,相当于长度,size。
(integer) 3
127.0.0.1:6379> zcount myset 0 100 #查询指定区间内的元素个数
(integer) 3
127.0.0.1:6379> zcount myset 0 2 #查询指定区间内的元素个数
(integer) 2
③总结:成绩表排序,工资表排序,年龄排序等需求可以用zset来实现!
3、SpringBoot整合Redis
3.1 项目框架
3.2 项目配置
3.2.1 项目依赖
<!--springBoot集成redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.5.4</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.5.4</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>2.5.4</version><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId><version>2.5.4</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.75</version></dependency>
3.2.2 配置文件
server.port=8000
spring.redis.host=127.0.0.1
#Redis服务器连接端口
spring.redis.port=6379
#Redis服务器连接密码(默认为空)
#spring.redis.password=123
#连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
#连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.pool.max-idle=8
#连接池中的最小空闲连接
spring.redis.pool.min-idle=0
#连接超时时间(毫秒)
spring.redis.timeout=10000
3.3 使用redis
User类
package com.byd.redis.entity;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {private static final long serialVersionUID = -1L;private Integer id;private String name;private Integer age;}
CatchService类
package com.byd.redis.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class CatchService {@Autowiredprivate 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);}
}
测试类
package com.byd;
import com.byd.redis.entity.User;
import com.byd.redis.service.CatchService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@SpringBootTest(classes = RedisApplication.class)
class AppTest {public static final int ID = 123;public static final int AGE = 12;@Autowiredprivate CatchService cacheService;@Autowiredprivate StringRedisTemplate stringRedisTemplate;/*** 功能描述:添加字符串到redis*/@Testvoid add() {cacheService.add("test", 1234);}/*** 功能描述:添加对象至redis*/@Testvoid addObject() {User user = User.builder().id(ID).name("小明").age(AGE).build();cacheService.add(user.getId(), user);}@Testvoid get() {String test = cacheService.get("test");System.out.println("test = " + test);Boolean key = stringRedisTemplate.hasKey("test");System.out.println("key = " + key);}/*** 功能描述:添加对象集合至redis*/@Testvoid addObjects() {ArrayList<User> users = new ArrayList<>();User user = User.builder().id(ID).name("小明").age(AGE).build();users.add(user);cacheService.add("key", users, 1, TimeUnit.HOURS);}/*** 功能描述:获取对象*/@Testvoid getObject() {User object = cacheService.getObject(ID, User.class);System.out.println("object = " + object);}/*** 功能描述:获取对象集合*/@Testvoid getObjects() {List<User> users = cacheService.getList("key", User.class);System.out.println("users = " + users);}/*** 功能描述:添加 hash-set*/@Testvoid addHashCache() {cacheService.addHashCache("hashKey", "key", "value");}/*** 功能描述:获取 hash-set*/@Testvoid getHashCache() {Object hashCache = cacheService.getHashCache("hashKey", "key");System.out.println("hashCache = " + hashCache);}@Testvoid test() {stringRedisTemplate.opsForList().rightPush("mylist", "3");System.out.printf("myllist", stringRedisTemplate.opsForList().leftPop("mylist"));Long append1 = stringRedisTemplate.opsForValue().size("append");System.out.println("append1 = " + append1);String append = stringRedisTemplate.opsForValue().get("append");System.out.println("append = " + append);}
}
3.4 测试结果
打开桌面RedisDesktopManager,连上本地redis数据库,查看存储结果
可以看到测试成功!