aoe1231

看得完吗

Redis 入门

1、初识 Redis

1.1、认识 NoSQL

1.2、认识 Redis

Redis 诞生于2009年,全称是 Remote Dictionary Server,远程词典服务器,是一个基于内存的键值型 NoSQL 数据库。

特征:

  • 键值(key-value)型:value支持多种不同数据结构,功能丰富;
  • 单线程:每个命令具备原子性;
  • 低延迟,速度快(基于内存、IO多路复用、良好的编码);
  • 支持数据持久化;
  • 支持主从集群、分片集群;
  • 支持多语言客户端。

1.3、安装 Redis

1.3.1、Redis 安装说明

大多数企业都是基于 Linux 服务器来部署项目,而且 Redis 官方也没有提供 Windows 版本的安装包。因此我们会基于 Linux 系统来安装 Redis。

此处选择的 Linux 版本位 CentOS 7.

Redis 的官方网站地址:https://redis.io/

1.3.2、单机安装 Redis

1.3.2.1、安装 Redis 依赖

Redis 是基于 C 语言编写的,因此首选需要安装 Redis 所需要的 gcc 依赖。

yum install -y gcc tcl

1.3.2.2、上传压缩包并解压

将Redis压缩包 redis-6.2.13.tar.gz 上传到虚拟机的任意目录并进行解压:

tar -zxvf redis-6.2.13.tar.gz 

进入redis目录:

cd ./redis-6.2.13/

运行编译命令:

make && make install

如果没有出错,应该就安装成功了。默认的安装路径是在 /usr/local/bin 目录下。该目录已经默认配置到环境变量,因此可以在任意目录下运行这些命令。其中:

  • redis-cli:是 redis 提供的命令行客户端;
  • redis-server:是 redis 的服务端启动脚本;
  • redis-sentinel:是 redis 的哨兵启动脚本。

1.3.2.3、启动

安装完成后,在任意目录输入 redis-server 命令脚本可启动 Redis:

redis-server

1、默认启动

直接命令行输入 redis-server ,前台启动(ctrl+c 会退出)。

2、指定配置启动

如果要让 Redis以后台方式启动,则必须修改 Redis 配置文件,就在我们之前解压的 redis 安装包下(/usr/local/src/redis-6.2.13),名字叫 redis.conf。

我们先将这个配置文件备份一份:

cp redis.conf redis.conf.bak

然后修改 redis.conf 文件中的一些配置:

# 允许访问的地址,默认是 127.0.0.1,会导致只能在本地访问,修改为 0.0.0.0 则可以在任意IP访问,生产环境不要设置为0.0.0.0
bind 0.0.0.0
# 守护进程,修改位 yes 后即可后台运行
daemonize yes
# 密码,设置后访问 Redis 必须输入密码
requirepass 123456

 Redis 的其他常见配置:

# 监听的端口
port 6379
# 工作目录,默认是当前目录,也就是运行 redis-server 时的命令,日志、持久化等文件会保存在这个目录
dir .
# 数据库数量,设置为1,代表只使用1个库,默认16个库,编号0到15
databases 1
# 设置redis能够使用的最大内存
maxmemory 512mb
# 日志文件,默认为空,不记录日志,可以指定日志文件名
logfile "redis.log"

启动 Redis:

# 进入 Redis 安装目录
cd /usr/local/src/redis-6.2.13
# 启动
redis-server redis.conf

停止服务:

# 利用redis-cli来执行 shutdown 命令,即可停止 Redis 服务
# 因为之前配置了密码,因此需要通过 -u 来指定密码
redis-cli -u 123456 shutdown

3、开机自启

我们也可以通过配置来实现开机自启。首先,新建一个系统服务文件:

vi /etc/systemd/system/redis.service

内容如下:

[Unit]
Description=redis-server
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /home/redis-6.2.13/redis.conf
PrivateTmp=true

[Install]
WantedBy=multi-user.target

然后重载系统服务:

systemctl daemon-reload

现在,我们可以用下面这组命令来操作redis了:

# 启动
systemctl start redis
# 停止
systemctl stop redis
# 重启
systemctl restart redis
# 查看状态
systemctl status redis

执行下面的命令,可以让 redis 开机自启:

systemctl enable redis

2、Redis 客户端

安装完成 Redis,我们就可以操作 Redis,实现数据的 CRUD 了。这需要用到 Redis 客户端,包括:

  • 命令行客户端;
  • 图形化桌面客户端;
  • 编程客户端。

2.1、Redis 命令行客户端

Redis 安装完成后就自带了命令行客户端:redis.cli,使用方式如下:

redis-cli [options] [commands]

其中常见的 options 有:

  • -h 127.0.0.1:指定要连接的 redis 节点的 IP 地址,默认是 127.0.0.1;
  • -p 6379:指定要连接的 redis 节点的端口,默认是 6379;
  • -a 123456:指定 redis 的访问密码。

其中 commands 就是 redis 的操作命令,例如:

  • ping:与 redis 服务端做心跳测试,服务端正常返回 pong。

不指定 commands 时,会进入 redis-cli 的交互控制台。

[root@test-host ~]# redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> ping
(error) NOAUTH Authentication required.
127.0.0.1:6379> redis-cli -h 127.0.0.1 -a 123456
(error) ERR unknown command `redis-cli`, with args beginning with: `-h`, `127.0.0.1`, `-a`, `123456`,
127.0.0.1:6379>
[root@test-host ~]# redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379>
[root@test-host ~]# redis-cli -h 127.0.0.1 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379>
[root@test-host ~]# redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set name jack
OK
127.0.0.1:6379> set age 21
OK
127.0.0.1:6379> get name
"jack"
127.0.0.1:6379> get age
"21"
127.0.0.1:6379>

2.2、图形化桌面客户端

GitHub 上的大神写了 Redis 的图形化桌面客户端,地址:https://github.com/uglide/RedisDesktopManager 。不过该仓库提供的是 RedisDesktopManager 的源码,并未提供 Windows 安装包。

在下面这个仓库可以找到安装包:https://github.com/lework/RedisDesktopManager-Windows/releases

3、Redis 命令

3.1、Redis 数据结构介绍

Redis 是一个 key-value 的数据库,key 一般是 String 类型,不过 value 的类型多种多样:

  • String:hello world
  • Hash:{name:"jack", age:23}
  • List:[A -> B -> C -> C]
  • Set:{A, B, C}
  • SortedSet:{A:1, B:2, C:3}
  • GEO:{A:(120.3, 30.5)}
  • BitMap:0101110001101
  • HyperLog:011100001010

3.2、Redis 通用命令

通用指定是部分数据类型的,都可以使用的指令,常见的有:

  • KEYS:查看符合模板的所有 key,不建议在生产环境设备上使用;
    127.0.0.1:6379> keys name
    1) "name"
  • DEL:删除一个指定的key。
    127.0.0.1:6379> mset k1 v1 k2 k2 k3 v3
    OK
    127.0.0.1:6379> keys *
    1) "k2"
    2) "age"
    3) "k3"
    4) "k1"
    127.0.0.1:6379> del k1 k2 k3
  • EXISTS:判断某一个键是否存在,1表示存在,0表示不存在。
    127.0.0.1:6379> EXISTS name
    (integer) 1
  • EXPIRE:给一个 key 设置有效期,有效期到期时该 key 会被自动删除。
    # 设置 age 的剩余有效期为20秒
    127.0.0.1:6379> expire age 20
    (integer) 1
  • TTL:查看一个 KEY 的剩余有效期。
  • 127.0.0.1:6379> expire age 20
    (integer) 1
    127.0.0.1:6379> TTL age
    (integer) -2
    127.0.0.1:6379> TTL age
    (integer) -2
    127.0.0.1:6379> keys *
    1) "name"
    127.0.0.1:6379> expire name 1
    (integer) 1
    127.0.0.1:6379> keys *
    (empty array)
    127.0.0.1:6379> set age 18
    OK
    127.0.0.1:6379> TTL name
    (integer) -2
    127.0.0.1:6379> TTL age
    (integer) -1

通过 help [command] 可以查看一个命令的具体用法,例如:

127.0.0.1:6379> help keys

  KEYS pattern
  summary: Find all keys matching the given pattern
  since: 1.0.0
  group: generic

3.3、String 类型

String 类型,也就是字符串类型,是 Redis 中最简单的存储类型。其 value 是字符串,不过根据字符串的格式不同,又可以分为3类:

  • string:普通字符串;
  • int:整数类型,可以做自增、自减操作;
  • float:浮点类型,可以做自增、自减操作。

不管是哪种格式,底层都是字节数组形式存储,只不过是编码方式不同。字符串类型的最大空间不能超过 512m。

3.3.1、String 类型的常见命令

String 的常见命令有:

  • SET:添加或者修改已经存在的一个String类型的键值对;
  • GET:根据 key 获取 String 类型的 value;
  • MSET:批量添加多个 String 类型的键值对;
  • MGET:根据多个 key 获取多个 String 类型的 value;
  • INCR:让一个整型的 key 自增1;
  • INCRBY:让一个整型的 key 自增并指定步长,例如:incrby num2 让 num 值自增2;
  • INCRBYFLOAT:让一个浮点类型的数字自增并指定步长;
  • SETNX:添加一个 String 类型的键值对,前提是这个 key 不存在,否则不执行;如 setnx name jack 和 set name jack nx 等效。
  • SETEX:添加一个 String 类型的键值对,并且指定有效期。如 setex name 10 jack 和 set name jack ex 10 等效。

3.4、key 的结构

Redis 的 key 允许有多个单词形成层级结构,多个单词之间用 ':' 隔开,格式举例如下:项目名:业务名:类型:id 。

如果 value 是一个 Java 对象,例如一个 User 对象,则可以将对象序列化为 JSON 字符串后存储:

key value
heima:user:1 {"id":1, "name":"Jack","age":21}
heima:product:1 {"id":1,"name":"小米11","price":4999}

3.5、Hash 类型

Hash 类型,也叫散列,其 value 是一个无序字典,类似于 Java 中的 HashMap 结构。String 结构是将对象序列化为 JSON 字符串后存储,当需要修改对象某个字段时很不方便,Hash 结构可以将对象中的每个字段独立存储,可以针对单个字段做 crud。

3.5.1、Hash 类型的常见命令

Hash 类型的常见命令有:

  • HSET key field value:添加或者修改 hash 类型的 field 的值;如 HSET user name jack
  • HGET key field:获取一个 hash 类型 key 的 field 的值;如 HGET user name
  • HMSET:批量添加多个 hash 类型 key 的 field 的值;如 HSET user name jack age 18
  • HMGET:批量获取多个 hash 类型的 key 的field 的值;如 HMGET user name age
  • HGETALL:获取一个 hash 类型的 key 中的所有的 field 的 value;如 HGETALL user
  • HKEYS:获取一个 hash 类型的 key 中的所有的 field;如 HKEYS user
  • HVALS:获取一个 hash 类型的 key 中的所有的 value;如 HVALS user
  • HINCRBY:让一个 hash 类型 key 的字段自增并指定步长;如 HINCRBY user age
  • HSETNX:添加一个 hash 类型的 key 的 field 值,前提是这个 field 不存在,否则不执行。如 HSETNX user name lisi(如果已经设置过,那么该次设置无效)

3.6、List 类型

Redis 中的 List 类型与 Java 中的 LinkedList 类似,可以看作是一个双向链表结构。既可以支持正向检索也可以支持反向检索。

特征也与 LinkedList 类似:

  • 有序;
  • 元素可以重复;
  • 插入和删除快;
  • 查询速度一般。

3.6.1、List 类型的常见命令

List 的常见命令有:

  • LPUSH key element ...:向列表左侧插入一个或多个元素;如 LPUSH users 1 2 3
  • LPOP key:移除并返回列表左侧的第一个元素,没有则返回 nil;如 RPOP users 1(从左侧取1个元素)
  • RPUSH key element ...:向列表右侧插入一个或多个元素;如 RPUSH users 1
  • RPOP key:移除并返回列表右侧的第一个元素,没有则返回 nil;如 RPOP users 1(从右侧取1个元素)
  • LRANGE key star end:返回一段角标范围内的所有元素;LRANGE users 1 2(索引从0开始,包括边界1和2,不会从列表中删除这些元素)
  • BLPOP 和 BRPOP:与 LPOP 和 RPOP 类似,只不过在没有元素时等待指定时间,而不是直接返回 nil。如 BLPOP users 100(从左侧取1个元素,如果没有则等100秒)

3.7、Set 类型

Redis 的 Set 结构与 Java 中的 HashSet 类似,可以看作是一个 value 为 null 的 HashMap。因为也是一个 hash 表,因此具备与 HashSet 类似的特征:

  • 无序;
  • 元素不可重复;
  • 查找快;
  • 支持交集、并集、差集等功能。

3.7.1、Set 类型的常见命令

String 的常见命令有:

  • SADD key member ... :向 set 中添加一个或多个元素;如 SADD s1 a b c
  • SREM key memeber ...:移除 set 中的指定元素;如 SREM s1
  • SCARD key:返回 set 中元素的个数;如 SCARD s1
  • SISMEMBER key member:判断一个元素是否存在于 set 中。如 SISMEMBER s1 a
  • SMEMBERS key:获取 set 中所有的元素;如 SMEMBERS s1
  • SINTER key1 key2 ... :求 key1、key2 ... 的交集;如 SINTER s1 s2
  • SDIFF key1 key2 ...:求 key1和key2的差集(key1中有而key2中没有的元素);如 SDIFF s1 s2
  • SUNION key1 key2 ... :求 key1 和 key2 的并集。如 SUNION s1 s2

3.8、SortedSet 类型

Redis 的 SortedSet 是一个可排序的 set 集合,与 Java 中的 TreeSet 有些类似,但底层数据结构却差别很大。SortedSet 中的每一个元素都带有一个 score 属性,可以基于 score 属性对元素排序,底层的实现是一个跳表(SkipList)加 hash 表。

SortedSet 具备以下特性:

  • 可排序;
  • 元素不重复;
  • 查询速度快。

因为 SortedSet 的可排序特性,经常被用来实现排行榜这样的功能。

3.8.1、SortedSet 类型的常见命令

SortedSet 的常见命令有:

  • ZADD key score member:添加一个或多个元素到 sorted set,如果已经存在则更新其 score 值;ZADD students 85 jack 89 lucy 95 tom
  • ZREM key member:删除 sorted set 中的一个指定元素;ZREM students tom
  • ZSCORE key member:获取 sorted set 中的指定元素的 score 值;ZSCORE students jack
  • ZRANK key member:获取 sorted set 中的指定元素的排名;ZRANK students jack
  • ZCARD key:获取 sorted set 中的元素个数;ZCARD students
  • ZCOUNT key min max:统计 score 值在给定范围内的所有元素个数;ZCOUNT students 80 90
  • ZINCRBY key increment member:让 sorted set 中的指定元素自增,步长为指定的 increment 的值;ZINCRBY students 2 jack
  • ZRANGE key min max:按照 score 排序后,获取指定排名范围内的元素;ZRANGE students 0 2(即前3名)
  • ZRANGEBYSCORE key min max:按照 score 排序后,获取指定 score 范围内的元素;
  • ZDIFF、ZINTER、ZUNION:求差集、交集、并集。

注意:所有的排名默认都是升序,如果要降序则在命令的 Z 后面添加 REV 即可(如 ZRANK 改成降序 ZRAEVRANK)。

4、Redis 的 Java 客户端

在 Redis 官网中提供了各种语言的客户端,地址:https://redis.io/clients

  • jedis:以 Redis 命令作为方法名称,学习成本低,简单实用。但是 Jedis 实例是线程不安全的,多线程环境下需要基于连接池来使用。
  • lettuce:Lettuce 是基于 Netty 实现的,支持同步、异步和响应式编程方式,并且是线程安全的。支持 Redis 的哨兵模式、集群模式和管道模式。
  • Redisson:Redisson 是一个基于 Redis 实现的分布式、可伸缩的 java 数据结构集合。包含了诸如 Map、Queue、Lock、Semaphore、AtomicLong 等强大功能。

4.1、Jedis

Jedis 的官网地址:https://github.com/redis/jedis

1、引入依赖

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.7.0</version>
        </dependency>

2、建立连接

private Jedis jedis;

@BeforeEach
void setUp() {
    // 建立连接
    jedis = new Jedis("192.168.1.1", 6379);
    // 设置密码
    jedis.auth("123456");
    // 选择库
    jedis.select(0);
}

3、测试 string

    private static void testString() {
        // 插入数据,方法名称就是 redis 命令名称,非常简单
        String result = jedis.set("name", "zhangsan");
        System.out.println("result=" + result);
        // 获取数据
        String name = jedis.get("name");
        System.out.println("name=" + name);
    }

结果:
result=OK
name=zhangsan

4、释放资源

jedis.close()

代码演示:

public class TestJedis {
    private Jedis jedis;

    @Before
    public void setUp() throws Exception {
        jedis = new Jedis("127.0.0.1", 6379);
        jedis.auth("123456");
        jedis.select(0);
    }

    @Test
    public void testString() {
        // 插入数据,方法名称就是 redis 命令名称,非常简单
        String result = jedis.set("name", "zhangsan");
        System.out.println("result=" + result);
        // 获取数据
        String name = jedis.get("name");
        System.out.println("name=" + name);
    }

    @Test
    public void testHash() {
        // 插入 hash 数据
        jedis.hset("user:1", "name", "Jack");
        jedis.hset("user:1", "age", "21");
        // 获取
        Map<String, String> map = jedis.hgetAll("user:1");
        System.out.println(map);
    }

    @After
    public void after() throws Exception {
        jedis.close();
    }
}

4.1.1、Jedis 连接池

Jedis 本身是线程不安全的,并且频繁地创建和销毁连接会有性能损耗,因此我们推荐大家使用 Jedis 连接池代替 Jedis 的直连方式。

public class JedisConnectionFactory {

    private static final JedisPool jedisPool;

    static {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 最大连接
        jedisPoolConfig.setMaxTotal(8);
        // 最大空闲连接
        jedisPoolConfig.setMaxIdle(8);
        // 最小空闲连接
        jedisPoolConfig.setMinIdle(0);
        // 设置最长等待时间 ms(没有空闲连接的等待时间)
        jedisPoolConfig.setMaxWaitMillis(200);
        jedisPool = new JedisPool(jedisPoolConfig, "127.0.0.1", 6379, 1000, "123456");
    }

    // 获取 Jedis 对象
    public static Jedis getJedis() {
        return jedisPool.getResource();
    }

}

4.2、SpringDataRedis

SpringDataRedis 是 Spring 中数据操作的模块,包含对各种数据库的集成,其中对 Redis 的集成模块就叫做 SpringDataRedis,官网地址:https://spring.io/projects/spring-data-redis

  • 提供了对不同 Redis 客户端的整合(Lettuce 和 Jedis);
  • 提供了 RedisTemplate 统一 API 来操作 Redis;
  • 支持 Redis 的发布订阅模型;
  • 支持 Redis 哨兵和 Redis 集群;
  • 支持基于 Lettuce 的响应式编程;
  • 支持基于 JDK、JSON、字符串、Spring 对象的数据序列化及反序列化;
  • 支持基于 Redis 的 JDKCollection 实现。

4.2.1、SpringDataRedis 快速入门

SpringDataRedis 中提供了 RedisTemplate 工具类,其中封装了各种对 Redis 的操作,并且将不同数据类型的操作 API 封装到了不同的类型中。

API 返回值类型 说明
redisTemplate.opsForValue() ValueOperations 操作 String 类型数据
redisTemplate.opsForHash() HashOperations 操作 Hash 类型数据
redisTemplate.opsForList() ListOperations 操作 List 类型数据
redisTemplate.opsForSet() SetOperations 操作 Set 类型数据
redisTemplate.opsForZSet() ZSetOperations 操作 SortedSet 类型数据
redisTemplate   通用的命令

SpringBoot 已经提供了对 SpringDataRedis 的支持,使用非常简单:

1、引入依赖

        <!-- Redis 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- 连接池依赖 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

2、配置文件

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password: 123456
    lettuce:
      pool:
        max-active: 8 # 最大连接
        max-idle: 8 # 最大空闲连接
        min-idle: 0 # 最小空闲连接
        max-wait: 100 # 连接等待时间

3、注入 RedisTemplate

@Autowired
private RedisTemplate redisTemplate;

4、编写测试

@SpringBootTest
class SpringBootRedisStudyApplicationTests {
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testString() {
        // 插入一条 String 类型数据
        redisTemplate.opsForValue().set("name", "李四");
        // 读取一条 String 类型数据
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println("name=" + name);
    }
}

4.2.2、SpringDataRedis 的序列化方式

RedisTemplate 可以接收任意的 Object 作为值写入 Redis,只不过写入前会把 Object 序列化为字节形式,默认是采用 JDK 序列化。

缺点:可读性差、内存占用较大。

我们可以自定义 RedisTemplate 的序列化方式,代码如下:

        <!-- jackson 依赖 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // 创建 Template
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // 设置连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 设置序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        // key 和 value 
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        // value 和 hashValue 采用 Json 序列化
        redisTemplate.setValueSerializer(jsonRedisSerializer);
        redisTemplate.setValueSerializer(jsonRedisSerializer);
        return redisTemplate;
    }
}

4.2.3、StringRedisTemplate

尽管 JSON 的序列化方式可以满足我们的要求,但依然存在一些问题,如:

{
    "@class": "com.redis.pojo.User",
    "name": "Jack",
    'age": 21
}

为了在反序列化时知道对象的类型,JSON 序列化器会将类的 class 类型写入 json 的结果中,存入 Redis,会带来额外的内存开销。

为了节省空间,我们并不会使用 JSON 序列化器来处理 Value,而是统一使用 String 序列化器,要求只能存储 String 类型的 key 和 value。当需要存储 Java 对象时,手动完成对象的序列化和反序列化。

Spring默认提供了一个 StringRedisTemplate 类,它的 key 和 value 的序列化方式默认就是 String 的方式。省去了我们自定义 RedisTemplate 的过程:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String name;
    private int age;
}

@SpringBootTest
public class Test {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    // JSON 工具
    private static final ObjectMapper mapper = new ObjectMapper();

    @Test
    public void testStringTemplate() throws JsonProcessingException {
        // 准备对象
        User user = new User("Jack", 18);
        // 手动序列化
        String json = mapper.writeValueAsString(user);
        // 写入一条数据到 Redis
        stringRedisTemplate.opsForValue().set("user:200", json);
        // 读取数据
        String val = stringRedisTemplate.opsForValue().get("user:200");
        // 反序列化
        User user1 = mapper.readValue(val, User.class);
        System.out.println("user1=" + user1);
    }

    @Test
    public void testHash() {
        stringRedisTemplate.opsForHash().put("user:400", "name", "Jack");
        stringRedisTemplate.opsForHash().put("user:400", "age", "20");

        Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("user:400");
        System.out.println("entries=" + entries);
    }
}

 

posted on 2023-08-10 10:59  啊噢1231  阅读(61)  评论(0编辑  收藏  举报

导航

回到顶部