文章目录
- [1. NoSQL](#1. NoSQL)
- [2. Redis介绍](#2. Redis介绍)
- [3. Redis的下载与安装](#3. Redis的下载与安装)
-
- [3.1 Windows版](#3.1 Windows版)
- [3.2 Linux版](#3.2 Linux版)
- [4. Redis的数据类型](#4. Redis的数据类型)
- [5. Redis常用命令](#5. Redis常用命令)
-
- [5.1 操作字符串的命令](#5.1 操作字符串的命令)
- [5.2 操作哈希结构的命令](#5.2 操作哈希结构的命令)
- [5.3 操作列表的命令](#5.3 操作列表的命令)
- [5.4 操作set集合的命令](#5.4 操作set集合的命令)
- [5.5 操作zset集合的命令](#5.5 操作zset集合的命令)
- [5.6 Redis通用命令](#5.6 Redis通用命令)
- [5.7 其他命令](#5.7 其他命令)
- [6. 在Java中操作Redis](#6. 在Java中操作Redis)
-
- [6.1 Redis的Java客户端](#6.1 Redis的Java客户端)
- [6.2 Spring Data Redis快速入门](#6.2 Spring Data Redis快速入门)
1. NoSQL
NoSQL(Not Only SQL),不仅仅是SQL,泛指关系型数据库。NoSQL数据库并不是要取代关系型数据库,而是作为关系型数据库的一种补充。
数据库有标准和方言之分,比如SQL可以操作所有RDBMS,但不同RDBMS语法方面会有所差异(sql方言)。
关系型数据库(RDBMS):全都是以表的形式存储数据,以约束维护数据关系,支持事务。
-
特点:数据结构化存储,语法非常严谨,不容易出错。
-
常见的有:MySQL、SQLServer、DB2、Oracle、以及国产数据库(达梦和金仓)等
-
三高问题:
-
高并发问题:关系型数据库如果要提供高并发的能力,需要的代价比较大。
高性能问题:快速从海量数据里找到并操作某些数据,成本高昂。
高扩展性问题:集群+分布式,数据库增加、减少节点,或者做数据的迁移 都非常麻烦。
-
非关系型数据库(NoSQL):泛指一切不以表形式存储数据、不使用约束维护关系的数据库。
-
优点:非常灵活,性能强大,高并发,高扩展性(更容易进行水平扩展)。
-
缺点:不严谨。
-
常见的有:
- Reids,键值对结构的数据库。
- MongoDB,文档型数据库,每一条数据存储成一个json对象。
- HBase,列式数据库,可以很方便的存储海量数据。
- Neo4j,图数据库,更适合于维护拓扑结构的关系,比如 人际关系。
- ...
2. Redis介绍
Redis官网:https://redis.io/
Redis中文网:http://redis.cn/
Redis,也是NoSQL数据库家族的一员,由一位意大利小哥Salvatore Sanfilippo 用C语言开发的一款开源的高性能键值对(key-value)数据库。据官方爆料说它并发能力很强可以达到100000+的QPS(每秒内查询次数),使得它非常适合作为分布式缓存和消息中间件来使用。
Redis的特点:
- 基于内存存储,读写性能高。
- 适合存储热数据(比如 热点商品,新闻,资讯等)
- 企业应用广泛。(有各种各样的使用场景)
Redis存储数据的value支持很多种数据类型,比如5种常用的数据类型:
- 字符串 String
- 列表 List
- 集合 Set
- 有序集合 zset (Sorted Set)
- 哈希 Hash
扩展:Redis默认端口号是6379,对应手机9键中MERZ四个字母,而Merz是一个意大利的女明星,作者极度厌恶这个女星。而且波浪哥这个人平常喜欢玩梗,一次与朋友交流的时候,造了这个词"MERZ",形容愚蠢(与stupid含义相同),当要给Redis设置默认端口号的时候,波浪哥也没多想,直接就把6379拿过来用了。😭
Redis是单线程+多路IO复用技术:???多路复用是指使用一个线程来检查多个文件描述符( Socket )的就绪状态,比如调用select和poll函数,传入多个文件描述符,如果有一个文件描述符就绪,则返回,否则阻塞直到超时。得到就绪状态后进行真正的操作可以在同一个线程里执行,也可以启动线程执行(比如使用线程池)。
3. Redis的下载与安装
Redis一开始只支持Linux系统,随着Redis的普及和用户群体的扩大,越来越多的开发者希望能够在其他操作系统上使用Redis,包括:linux、macos、windows平台。
3.1 Windows版
1、Windows版的Redis,由微软团队提供:(Microsoft Archive)
-
该项目有Redis2和Redis3版本,目前已经停止维护了。
-
最后一个稳定版是 3.2.100 (2016年发布)。
tporadowski大神,也提供了一个支持windows平台的Redis :
- 下载地址:https://github.com/tporadowski/redis/releases
- 支持版本:Reids5
2、Reids的目录结构:
3、Redis的客户端:(用于连接Redis服务器的工具)
- 命令行客户端,redis-cli
- 可视化工具,RESP、ARDM、TinyRDM
- Java代码,Spring Boot Data Redis
4、Redis的使用:
(1)启动Redis服务:
- 默认启动:双击 redis-server.exe 即可
- 加载配置文件启动:
redis-server.exe redis.windows.conf
(在redis工作目录中执行)
(2)使用客户端连接Redis:(需要提供ip,端口,密码)
-
本机连接:双击 redis-cli.exe 即可
-
连接其他电脑上的redis:
sh
# 连接其他电脑上的redis命令
redis-cli.exe -h ip地址 -p 端口号 -a 密码
# 例如 通过ip和端口号连接本地redis
redis-cli.exe -h ip 127.0.0.1 -p 6379
3.2 Linux版
下载地址:https://download.redis.io/releases/
4. Redis的数据类型
Redis中的数据都是以键值对的方式存储的。
-
key:始终是字符串或字节数组(最大512MB)
-
value:有5种常见的数据类型 (每种类型都有不同的使用场景)
- Stirng:字符串,最最常用。
- hash:哈希结构,相当于Java里的HashMap。(场景:用于存储一组相关的数据,比如购物车,而且每个哈希表可以存储 2^32-1 个键值对)
- list:列表结构,有序可重复,相当于Java里的LinkedList。(场景:模拟队列)
- set:无序不重复的数据集合,相当于Java里的HahsSet。(场景:可以做集合间的运算:交集、并集、差集)
- zset:也叫sorted set,有序不重复的集合,集合中每个元素关联一个分数(score),根据分数升序排序,没有重复元素。(场景:排行榜)
扩展:bitmap
5. Redis常用命令
Redis常用命令中文手册:https://www.redis.net.cn/order/
5.1 操作字符串的命令
操作字符串的常用命令:
-
SET key value:存数据,如果key存在会覆盖值。
-
GET value:取数据。
-
DEL key:删除key。
-
SETEX key seconds value:存储数据,并设置有效期(单位是秒)。
- 应用场景:手机验证码、在有效时间内支付。
-
SETNX key value:存储数据,只要在key不存在的情况下,才可以存数据。
- 应用场景:分布式锁。
扩展命令:
-
TTL key:查看key的过期时间 (不设置过期时间的话,key默认是-1,表示永久有效)
-
INCR key:让key的值自增 (increment 增加,场景:可以作为分布式id)
示例:
shell
127.0.0.1:6379> set name robin # 存一个字符串数据 key是name value是robin
OK
127.0.0.1:6379> get name # 获取key为name对应的value值
"robin"
127.0.0.1:6379> del name # 删除key为name的数据
(integer) 1
127.0.0.1:6379> get name # 获取key为name对应的value值,返回值:nil表示获取不到
(nil)
#---------------------------------------------------------------------
127.0.0.1:6379> setex check_code 10 cat # 存一个字符串数据,有效期是10秒,10s后自动消失
OK
127.0.0.1:6379> ttl check_code # 查看key的过期时间
(integer) 2 # 还剩两秒
127.0.0.1:6379> ttl check_code
(integer) -2 # 已过期
127.0.0.1:6379> get check_code # 到10s了,数据已经没有了
(nil)
#---------------------------------------------------------------------
127.0.0.1:6379> setnx lock 1 #setnx只有在key不存在时设置key的值
(integer) 1
127.0.0.1:6379> get lock
"1"
127.0.0.1:6379> setnx lock 2
(integer) 0 # 返回值0:表示这个key已经存在了,所以设置失败
5.2 操作哈希结构的命令
Redis中hash是一个string类型的 field 和 value 的映射表,hash特别适合用于存储对象。
操作hash的常用命令:
- HSET key field value :存数据,把field-value存到key对应的hash表里。
- HGET key field :取数据,从key对应的hash表里,找到field对应的数据。
- HDEL key field : 删除数据。从key对应的hash表里,删除掉field
- HKEYS key : 获取key对应的hash表里,所有field。
- HVALS key : 获取key对应的hash表里,所有value。
- HGETALL key : 获取key对应的hash中,所有filed-value对。
示例:
shell
127.0.0.1:6379> hset user1 name tom # 向key为user1的hash表里,存一个fv对
(integer) 1
127.0.0.1:6379> hset user1 age 20
(integer) 1
127.0.0.1:6379> hget user1 age # 从key为user1的hash表里,获取age的值
"20"
127.0.0.1:6379> hget user1 name # 从key为user1的hash表里,获取name的值
"tom"
127.0.0.1:6379> hkeys user1 # 获取key为user1的hash表里,所有field
1) "name"
2) "age"
127.0.0.1:6379> hvals user1 # 获取key为user1的hash表里,所有value
1) "tom"
2) "20"
127.0.0.1:6379> hdel user1 age # 从key为user1对应的hash表里,删除字段age
(integer) 1
127.0.0.1:6379> hgetall user1 # 从key为user1对应的hash表里,获取所有filed-value对
1) "name"
2) "tom"
5.3 操作列表的命令
Redis 列表是简单的字符串列表,按照插入顺序排序。
操作列表的常用命令:(push插入、pop弹出)
- LPUSH key value1 [value2 ...]:将一个或多个值,从队列左边插到右边。
- LRANGE key start stop:获取列表指定范围内的元素。
- start和stop是索引值,索引从0开始,0表示第一个,-1表示最后一个。
- RPOP key:移除并获取列表最后一个元素
- LLEN key:获取列表的长度。
- BRPOP key1 [key2 ...] timeout:移出并获取列表的最后一个元素; 如果列表没有元素将会阻塞列表,直到等待超时或发现可弹出元素为止。
示例:
shell
127.0.0.1:6379> lpush mylist msg1 msg2 msg3 msg4 #向mylist对应的列表里,从左边依次添加数据
(integer) 4
127.0.0.1:6379> lrange mylist 0 3 #从mylist对应的列表里,查询索引0到索引3的数据(包含头和尾)
1) "msg4"
2) "msg3"
3) "msg2"
4) "msg1"
/*
msg4->msg3->msg2->msg1
*/
127.0.0.1:6379> llen mylist #从mylist对应的列表里,查询列表的长度
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1 #从mylist对应的列表里,查询索引0到 倒数第1个值(查询全部)
1) "msg4"
2) "msg3"
3) "msg2"
4) "msg1"
127.0.0.1:6379> lrange mylist 0 -2 #从mylist对应的列表里,查询索引0到 倒数第2个值
1) "msg4"
2) "msg3"
3) "msg2"
127.0.0.1:6379> rpop mylist #从mylist对应的列表里,弹出最右边的值
"msg1"
127.0.0.1:6379> rpop mylist #从mylist对应的列表里,弹出最右边的值
"msg2"
127.0.0.1:6379> rpop mylist #从mylist对应的列表里,弹出最右边的值
"msg3"
127.0.0.1:6379> rpop mylist #从mylist对应的列表里,弹出最右边的值
"msg4"
127.0.0.1:6379> rpop mylist #从mylist对应的列表里,弹出最右边的值。已经全部弹出,队列里空了
(nil)
127.0.0.1:6379> brpop mylist 5 #从mylist对应的列表里,弹出最右边的值。如果没有值,就等待5s终
(nil)
(5.06s)
5.4 操作set集合的命令
Redis中set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
操作set集合的常用命令:
- SADD key member1 [member2 ...] :向集合添加一个或多个成员。
- SREM key member1 [member2 ...] :移除集合中一个或多个成员。
- SMEMBERS key :返回集合中的所有成员。
- SCARD key :获取集合的长度。
- SINTER key1 [key2] :返回给定所有集合的交集。
- SUNION key1 [key2] :返回所有给定集合的并集。
- SDIFF key1 [key2] :返回给定所有集合的差集。
示例:
shell
127.0.0.1:6379> sadd set1 a b c # 向set1对应的set集合里添加多个成员
(integer) 3
127.0.0.1:6379> smembers set1 # 查询set1对应的set集合里所有的成员
1) "a"
2) "c"
3) "b"
127.0.0.1:6379> sadd set1 c d jackma # 向set1对应的集合里添加多个成员
(integer) 2 # 成功插入2个
127.0.0.1:6379> srandmember set1 # 从set1对应的set集合里随机获取一个
"a"
127.0.0.1:6379> srandmember set1
"jackma"
127.0.0.1:6379> scard set1 # 查询set1对应的set集合里成员的个数
(integer) 5
127.0.0.1:6379> srem set1 b # 从set1对应的set集合里,移除一个成员b
(integer) 1
127.0.0.1:6379> smembers set1
1) "jackma"
2) "c"
3) "a"
4) "d"
set集合运算:(交集、并集、差集)
shell
127.0.0.1:6379> sadd myset1 tom jerry jack rose # 向第1个set集合插入多个成员
127.0.0.1:6379> sadd myset2 tom robin jerry pony # 向第2个set集合插入多个成员
127.0.0.1:6379> sinter myset1 myset2 # sinter取交集:jerry,tom
127.0.0.1:6379> sunion myset1 myset2 # sunion取并集:pony,jack,robin,rose,jerry,tom
127.0.0.1:6379> sdiff myset1 myset2 # sdiff取差集:myset1-myset2=jack,rose
127.0.0.1:6379> sdiff myset2 myset1 # sdiff取差集:myset2-myset1=robin,pony
5.5 操作zset集合的命令
Redis有序集合zset是string类型元素的集合,且不允许有重复成员。每个元素都会关联一个double类型的分值(score) 。
注意事项:
- zset默认排序规则是升序
- 排名rank是从0开始,0表示第1名
操作有序集合zset的常用命令:
- ZADD key score1 member1 [score2 member2 ...] :向有序集合添加一个或多个成员,或者更新已存在成员的分数。
- ZRANGE key start stop [WITHSCORES] :通过索引区间返回有序集合中指定区间内的成员。(默认从小到大)
- ZINCRBY key increment member :有序集合中对指定成员的分数加上增量 increment。
- ZREM key member [member ...] :移除有序集合中的一个或多个成员。(remove)
示例:
shell
127.0.0.1:6379> zadd java1 80 tom 90 rose 59 toni #添加多个成员 到java1对应的zet集合里
(integer) 3
127.0.0.1:6379> zrank java1 tom #从java1集合里查询tom的排名(从0开始)
(integer) 1
127.0.0.1:6379> zscore java1 tom #从java1集合里查询tom的分值
"80"
127.0.0.1:6379> zrange java1 0 1 #范围查询(索引或排名)区间内的成员,包含头和尾
1) "toni"
2) "tom"
127.0.0.1:6379> zrange java1 0 1 withscores #范围查询(索引或排名)区间内的成员及分值,包含头和尾
1) "toni"
2) "59"
3) "tom"
4) "80"
127.0.0.1:6379> zrange java1 0 -1 withscores # 查询所有成员及分值,-1表示最后一个成员的索引。
1) "toni"
2) "59"
3) "tom"
4) "80"
5) "rose"
6) "90"
127.0.0.1:6379> zadd java1 99 toni #改toni的分值
(integer) 0
127.0.0.1:6379> zrange java1 0 -1 withscores
1) "tom"
2) "80"
3) "rose"
4) "90"
5) "toni"
6) "99"
127.0.0.1:6379> zincrby java1 1 toni # 给toni成绩加一分
"100"
127.0.0.1:6379> zrange java1 0 -1 withscores
1) "tom"
2) "80"
3) "rose"
4) "90"
5) "toni"
6) "100"
127.0.0.1:6379> zrem java1 tom #从java01里删除一个成员tom
(integer) 1
127.0.0.1:6379> zrange java1 0 -1 withscores
1) "rose"
2) "90"
3) "toni"
4) "100"
5.6 Redis通用命令
-
KEYS pattern:查找所有符合给定模式(pattern)的 key,支持通配符 *。
- keys * :表示查询当前redis实例里所有的key
- keys xxx*:表示查询当前redis实例里以xxx开头的key
- keys xxx?: 查询xxx + 一个任意字符的key (类似mysql模糊查询的_)
-
EXISTS key:判断key是否存在
-
TYPE key:返回key所存储value的类型。
-
TTL key:查看key的剩余过期时间(TTL,time to live),以秒为单位。
- 返回值-2:不存在。
- 返回值-1:永不过时。
- 正整数:剩余时间。
-
DEL key: 删除key
- 返回值1:表示删除成功。
5.7 其他命令
Redis中默认提供了16个数据库,从0开始,初始默认使用0号库,所有库的密码都是相同的。
select <dbid>
: 切换数据库。 例如:select 1 切换到1号库。dbsize
:查看当前数据库中key的数量。flushall
:通杀全部库。(清空所有数据库的所有key)
6. 在Java中操作Redis
6.1 Redis的Java客户端
如果我们想要使用Java程序操作Redis,就需要借助一个Redis的Java客户端作为桥梁,这些客户端提供了一系列的API,使得我们可以在Java代码中以编程的方式与Redis进行交互,本质和redis-cli命令行工具执行命令的效果是一样的。
Redis的Java客户端很多,官方推荐的有三种:
- Jedis:使用最广泛的Java客户端,它提供了一个简单易用的API,可以让你执行各种Redis命令。
- Lettuce:高性能的Java客户端,它提供了异步API,适用于响应式编程。
- Redisson:是在Redis的基础上实现的框架。它不仅提供了基本的Redis操作,还提供了许多高级功能,如 分布式锁 等。
而我们的老东家Spring,通过Spring Data Redis模块对Redis的底层操作进行了高度封装(默认使用Lettuce),使得开发者可以通过简单的配置和注解来访问和操作Redis服务。Spring Data Redis是Spring Data家族的一部分,它提供了一系列的抽象,让开发者能够以声明式的方式操作Redis数据库。而在SpringBoot项目中,还可以使用redis起步依赖: spring-boot-starter-data-redis,再次简化开发。
Spring Data Redis官网:https://spring.io/projects/spring-data-redis
在Spring Data Redis项目中,提供了一些高度封装的类,用于更加简便的操作Redis:
- RedisTemplate:操作Redis的模板类,它提供了操作Redis的一系列方法。(支持自定义序列化机制)
- 默认使用Jackson库进行序列化和反序列化操作。
- 会把我们的key和value,以字节数组的形式存储到redis里,不利于我们查找数据。
- StringRedisTemplate:是RedisTemplate的子类,默认采用String序列化方式,推荐使用。
Spring Data Redis,对相关API进行了归类封装,将同一类型操作封装为operation接口,具体分类如下:
- ValueOperations:string数据操作。
- SetOperations:set类型数据操作。
- ZSetOperations:zset类型数据操作。
- HashOperations:hash类型的数据操作。
- ListOperations:list类型的数据操作。
6.2 Spring Data Redis快速入门
1、导入Redis起步依赖
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2、配置redis连接信息
yml
spring:
redis:
host: localhost
port: 6379
#password:
database: 0 #使用0号数据库
3、使用StringRedisTemplate操作Redis:
java
package com.sky.test;
import com.alibaba.fastjson.JSON;
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.connection.DataType;
import org.springframework.data.redis.core.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* Redis测试类
*
* @author 白豆五
* @since 2024/4/1 10:52
*/
@SpringBootTest
public class RedisTest {
// 操作Redis的模板类
@Autowired
StringRedisTemplate stringRedisTemplate;
/**
* 测试Redis中字符串类型数据的操作。
*/
@Test
public void testValue() {
// 获取Redis字符串操作对象
ValueOperations valueOperations = stringRedisTemplate.opsForValue();
// 设置一个键值对
valueOperations.set("hello", "spring data redis");
// 获取并打印设置的值
Object o = valueOperations.get("hello");
System.out.println(o);
// 存储一个JSON字符串
HashMap<String, Object> map = new HashMap<>();
map.put("username", "tom");
map.put("age", 18);
valueOperations.set("mm", JSON.toJSONString(map));
Object value = valueOperations.get("mm");
System.out.println(value);
// 使用setex命令设置键的过期时间
valueOperations.set("hi1", "我1分钟过期", Duration.ofMinutes(1));
valueOperations.set("hi2", "我1分钟过期", 1, TimeUnit.MINUTES);
// 使用setnx命令演示条件设置,当键不存在时设置键值对
Boolean flag = valueOperations.setIfAbsent("id", 1);
System.out.println(flag); // 输出true,因为键"id"首次设置
flag = valueOperations.setIfAbsent("id", 1);
System.out.println(flag); // 输出false,因为键"id"已存在
}
/**
* 测试Redis的哈希操作
*/
@Test
public void testHash() {
// 获取HashOperations实例,用于操作Redis的哈希表
HashOperations hashOperations = stringRedisTemplate.opsForHash();
// 向"user1"的哈希表中添加"username"和"age"键值对
hashOperations.put("user1", "username", "tom");
hashOperations.put("user1", "age", 18);
// 获取"user1"哈希表中"username"键对应的值
Object username = hashOperations.get("user1", "username");
System.out.println(username);
// 获取"user1"哈希表中的所有键
Set keySet = hashOperations.keys("user1");
System.out.println(keySet);
// 获取"user1"哈希表中的所有值
List valueList = hashOperations.values("user1");
System.out.println(valueList);
}
/**
* 测试Redis的List操作。
*/
@Test
public void testList() {
// 获取List操作的接口
ListOperations listOperations = stringRedisTemplate.opsForList();
// 向列表"list1"的左侧添加三个元素
listOperations.leftPushAll("list1", "a", "b", "c");
// 获取列表"list1"的长度
Long size = listOperations.size("list1");
System.out.println(size);// 输出列表长度:3
// 获取列表"list1"中所有元素
List list = listOperations.range("list1", 0, -1);
System.out.println(list);// 输出列表内容:[c, b, a]
// 从列表"list1"的右侧弹出一个元素
Object element = listOperations.rightPop("list1");
System.out.println(element);// 输出弹出的元素:a
}
/**
* 测试Redis的Set操作。
*/
@Test
public void testSet() {
// 获取Set操作对象
SetOperations setOperations = stringRedisTemplate.opsForSet();
// 向"set1"集合中添加多个成员
setOperations.add("set1", "a", "b", "c");
// 获取"set1"集合中的所有成员
Set set = setOperations.members("set1");
System.out.println(set);
// 获取"set1"集合的成员数量
Long size = setOperations.size("set1");
System.out.println(size);// 输出集合大小: 3
// 从"set1"集合中移除成员"c"
setOperations.remove("set1", "c");
// 再次获取"set1"集合的成员数量
size = setOperations.size("set1");
System.out.println(size);// 输出集合大小: 2
}
/**
* 测试Redis的ZSet(有序集合)操作。
*
*/
@Test
public void testZset() {
// 获取ZSet操作的接口
ZSetOperations zSetOperations = stringRedisTemplate.opsForZSet();
// 向"java"键对应的有序集合中添加成员"tom",并设置分数为88
zSetOperations.add("java", "tom", 88);
// 添加成员"jack",分数为69
zSetOperations.add("java", "jack", 69);
// 添加成员"rose",分数为100
zSetOperations.add("java", "rose", 100);
// 获取成员"tom"的分数
Double tomScore = zSetOperations.score("java", "tom");
System.out.println(tomScore);// 输出: 88
// 为成员"tom"的分数增加10
zSetOperations.incrementScore("java", "tom", 10);
tomScore = zSetOperations.score("java", "tom");
System.out.println(tomScore);// 输出: 98
System.out.println("---------");
// 获取有序集合"java"中所有成员及其分数
Set set = zSetOperations.range("java", 0, -1);
for (Object member : set) {
// 输出每个成员及其分数
System.out.println(member + ":" + zSetOperations.score("java", member));
}
}
// 通用命令的操作
@Test
public void testCommons() {
// 判断元素是否存在
Boolean result = stringRedisTemplate.hasKey("user1");
System.out.println(result);
// 判断元素的类型
DataType type = stringRedisTemplate.type("166java");
System.out.println(type);
// 删除元素
Boolean flag = stringRedisTemplate.delete("166java");
System.out.println(flag);
// keys 通配符
Set set = stringRedisTemplate.keys("li*");
System.out.println(set);
}
}