• 92、Redis ------- 使用 Lettuce 操作 Redis 的方法和步骤----(文字讲解无代码)


    lettuce :英语的意思:生菜
    是一个用来操作redis的框架,springboot内置默认支持的也是 lettuce ,也可以自己改成 jedis
    Jedis 也是一个用来操作redis的框架

    在这里插入图片描述

    ★ Lettuce的核心API

    • RedisURI:用于封装Redis服务器的URI信息。

    • RedisClient:代表Redis客户端,如果连接Cluster模式的Redis,则使用RedisClusterClient。
      有点类似于redis-cli工具。

    • StatefulConnection:代表Redis连接的父接口,它派生了不少子接口来代表不同的连接。

    • RedisCommands:用于执行Redis命令的接口,它的方法几乎覆盖了Redis的所有命令(前面介绍的那些命令全部都支持)
      它的方法名和Redis命令名也是一一对应的,肯定一看就会,
      比如Redis对操作Hash对象提供了hmset命令,那RedisCommands就支持hmset()方法,
      它派生了一个RedisPubSubCommands子接口,用于运行消息发布/订阅的命令。

    ★ Lettuce编程步骤:

    使用Lettuce操作Redis的大致步骤如下:

    (1)定义RedisURI(有点类似于数据库的URL),再以RedisURI为参数,创建RedisClient(普通单机模式的redis)或RedisClusterClient(集群模式的redis)对象

    (2)调用 RedisClient 或 RedisClusterClient 的 connectXxx()方法 连接Redis服务器,根据所连接的Redis服务器的状态不同,该方法返回 StatefulRedisXxxConnection 连接对象

    (3)调用StatefulRedisXxxConnection连接对象的sync()、async()或reactive()方法创建同步、异步或反应式模式的RedisCommands对象

    sync:同步        async :异步        reactive:反应式
    
    • 1

    (4)调用RedisCommands执行Redis命令。这一步是变化最多的,因为RedisCommands可以执行Redis的全部命令

    (5)关闭资源,就是关闭连接。关闭资源时按照惯例“先开后闭”,因此先关闭与Redis的连接对象,再关闭RedisClient对象。

    redis的编程步骤:定义URI(指定连接的服务器) → 创建Client → 与服务器建立连接 → 创建RedisCommands 对象 → 通过 RedisCommands 对象来执行命令 → 关闭资源

    ★ 构建RedisURI:

    Lettuce提供了如下三种方式来构建RedisURI:

    方法1:调用静态的create()方法。这种方式要求把所有的连接信息都写在create()方法的String参数中。
    该String参数既支持单机模式的Redis,也支持集群模式的Redis,也支持哨兵模式的Redis。

    方法2: 调用Builder来构建。这种构建方式下,所有信息都通过Builder对应的方法逐项传入,因此可读性最好,这也是我所推荐的方式。

    方法3: 调用构造器来构建。这种方式是最不灵活的方式,因为它只能传入3个构造器参数,通过该方式构建RedisURI之后还需要调用它的setter方法对它进行设置,这种方式是最差的一种。

    官网中用Builder对应的方法构建RedisURI
    用梯子的话能更好的访问官网,但是此刻的官网进不去了,在维护
    在这里插入图片描述

    ★ 从RedisClient 到 StatefulConnection 连接对象

    ——用于获取与Redis服务器的连接

    以RedisURI为参数,调用RedisClient(或 RedisClusterClient 用于集群)的create()静态方法即可创建RedisClient(或RedisClusterClient)对象。

    根据Redis运行模式调用RedisClient或RedisClusterClient对象对应的connectXxx()方法获取StatefulConnection连接对象。

    StatefulConnection提供如下常用子接口:

    根据各种子接口,用来返回各种连接对象,如单机、集群、主从、哨兵
    StatefulRedisConnection: 最基本的Redis连接。
    StatefulRedisPubSubConnection: 带消息发布/订阅功能的Redis连接。
    StatufulRedisMasterSlaveConnection: 主从模式的Redis连接。
    StatefulRedisSentinelConnection: 哨兵模式的Redis连接。

    在这里插入图片描述
    **主从模式:**相当于redis有两个节点:主节点和从节点,主要是向主节点进行操作,如果主节点挂掉了,从节点顶上,从节点主要是提供一个数据备份的功能。

    **哨兵模式:**对主、从节点进行监视,当主节点出问题的时候,可以再从众多节点里面再找一个主节点出来。

    ★ 从StatefulConnection 到 RedisXxxCommands对象

    调用 StatefulRedisXxxConnection连接对象 的以下三个方法来创建 RedisXxxCommands对象

    sync(): 创建同步模式的RedisCommands对象。
    async(): 创建异步模式的RedisAsyncCommands对象。
    reactive(): 创建反应式模式的RedisReactiveCommands对象。

    RedisCommands的作用类似于redis-cli.exe工具,用于执行各种Redis命令。
    其中RedisAsyncCommands是异步版本,而RedisReactiveCommands则是反应式版本

    代码演示

    1、先创建一个maven项目

    然后导入lettuce的依赖:
    在这里插入图片描述

    第一种风格:使用同步的方式来操作redis数据库

    创建一个普通类,写一个main方法,然后通过同步的方式来操作redis数据库
    运行这个main方法,然后到redis数据库看是否是否都成功添加
    在这里插入图片描述
    在这里插入图片描述

    同步操作数据库的结果:
    在这里插入图片描述

    第二种风格:使用异步的方式来操作redis数据库

    直接拷贝上面同步的代码,然后把这个main方法给拆分成多个方法,看起来比较符合规范。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    异步操作redis数据库的结果,也是成功的。
    在这里插入图片描述

    第三种风格:使用反应式的方式来操作redis数据库

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    运行结果
    在这里插入图片描述

    redsi数据库,一样都有数据,表明用反应式操作数据库也成功了
    在这里插入图片描述

    反应式block方法的解释:SpringBoot 整合 R2DBC — R2DBC 就是 JDBC 的 反应式版本
    在这里插入图片描述

    完整代码

    Sync

    package cn.ljh.app;
    
    
    import io.lettuce.core.RedisClient;
    import io.lettuce.core.RedisURI;
    import io.lettuce.core.ScoredValue;
    import io.lettuce.core.api.StatefulRedisConnection;
    import io.lettuce.core.api.sync.RedisCommands;
    
    import java.time.Duration;
    import java.util.Map;
    
    //使用 Lettuce ,通过同步的方式来操作redis数据库
    public class Sync
    {
        public static void main(String[] args)
        {
    
            //1、定义RedisURI
            RedisURI uri = RedisURI.builder()
                    .withHost("127.0.0.1")
                    .withPort(6379)
                    //选择redis 16个数据库中的哪个数据库
                    .withDatabase(0)
                    .withPassword(new char[]{'1', '2', '3', '4', '5', '6'})
                    .withTimeout(Duration.ofMinutes(5))
                    .build();
            //2、创建 RedisClient 客户端
            RedisClient redisClient = RedisClient.create(uri);
    
            //3、获取连接
            StatefulRedisConnection connect = redisClient.connect();
    
            //4、创建RedisCommands----------------使用同步的方式来操作数据库
            RedisCommands cmd = connect.sync();
    
            //通过redis的命令进行各种操作
    
            //添加一个string对象
            cmd.set("name","ljh");
    
            //添加一个list对象
            cmd.lpush("schools","小学","中学","大学");
    
            //添加一个set对象
            cmd.sadd("items","电脑","鼠标","钱包");
    
            //添加zset对象,zset比set多一个score的分数功能,三种向zset对象添加元素的方法
            cmd.zadd("test",3.0,"java");
            cmd.zadd("test",3.2,"mysql",3.5,"nosql");
            cmd.zadd("test", ScoredValue.just(2.1,"jsp")
                    ,ScoredValue.just(2.2,"vue"));
    
            //添加一个hash对象
            cmd.hmset("user", Map.of("name","aaa","age","20","height","170"));
    
    
            //关闭资源
            connect.close();
            redisClient.shutdown();
    
        }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77

    ASync

    package cn.ljh.app;
    
    
    import io.lettuce.core.RedisClient;
    import io.lettuce.core.RedisURI;
    import io.lettuce.core.ScoredValue;
    import io.lettuce.core.api.StatefulRedisConnection;
    import io.lettuce.core.api.async.RedisAsyncCommands;
    
    import java.time.Duration;
    import java.util.Map;
    
    //使用 Lettuce ,通过异步的方式来操作redis数据库
    public class ASync
    {
        //redis客户端
        private RedisClient redisClient;
        //连接对象
        private StatefulRedisConnection connect;
    
        //初始化方法
        public void init()
        {
            //1、定义RedisURI
            RedisURI uri = RedisURI.builder()
                    .withHost("127.0.0.1")
                    .withPort(6379)
                    //选择redis 16个数据库中的哪个数据库
                    .withDatabase(1)
                    .withPassword(new char[]{'1', '2', '3', '4', '5', '6'})
                    .withTimeout(Duration.ofMinutes(5))
                    .build();
            //2、创建 RedisClient 客户端
            this.redisClient = RedisClient.create(uri);
    
            //3、获取连接
            this.connect = redisClient.connect();
        }
    
        //操作redis的命令
        public void accessRedis()
        {
            //4、创建 RedisAsyncCommands ----------------使用异步的方式来操作数据库
            RedisAsyncCommands cmd = connect.async();
    
            //通过redis的命令进行各种操作
    
            //添加一个string对象
            cmd.set("name", "ljh")
                    //作用:因为是异步的,在thenAccept方法里面等待这个set方法的结果出来后,再把set方法的结果处理掉,这里处理的方法是打印
                    .thenAccept(System.out::println);
    
            //添加一个list对象
            cmd.lpush("schools", "小学", "中学", "大学").thenAccept(System.out::println);
    
            //添加一个set对象
            cmd.sadd("items", "电脑", "鼠标", "钱包").thenAccept(System.out::println);
    
            //添加zset对象,zset比set多一个score的分数功能,三种向zset对象添加元素的方法
            cmd.zadd("test", 3.0, "java").thenAccept(System.out::println);
            cmd.zadd("test", 3.2, "mysql", 3.5, "nosql").thenAccept(System.out::println);
            cmd.zadd("test", ScoredValue.just(2.1, "jsp")
                    , ScoredValue.just(2.2, "vue")).thenAccept(System.out::println);
    
            //添加一个hash对象
            cmd.hmset("user", Map.of("name", "aaa", "age", "20", "height", "170"))
                    .thenAccept(System.out::println);
    
        }
    
        //关闭资源
        public void closeResource()
        {
            connect.close();
            redisClient.shutdown();
        }
    
    
        public static void main(String[] args)
        {
            ASync aSync = new ASync();
            aSync.init();
            aSync.accessRedis();
            aSync.closeResource();
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87

    Reactive

    package cn.ljh.app;
    
    
    import io.lettuce.core.RedisClient;
    import io.lettuce.core.RedisURI;
    import io.lettuce.core.ScoredValue;
    import io.lettuce.core.api.StatefulRedisConnection;
    import io.lettuce.core.api.async.RedisAsyncCommands;
    import io.lettuce.core.api.reactive.RedisReactiveCommands;
    import reactor.core.publisher.Mono;
    
    import java.time.Duration;
    import java.util.Map;
    
    //使用 Lettuce ,通过反应式的方式来操作redis数据库
    public class Reactive
    {
        //redis客户端
        private RedisClient redisClient;
        //连接对象
        private StatefulRedisConnection connect;
    
        //初始化方法
        public void init()
        {
            //1、定义RedisURI
            RedisURI uri = RedisURI.builder()
                    .withHost("127.0.0.1")
                    .withPort(6379)
                    //选择redis 16个数据库中的哪个数据库
                    .withDatabase(2)
                    .withPassword(new char[]{'1', '2', '3', '4', '5', '6'})
                    .withTimeout(Duration.ofMinutes(5))
                    .build();
            //2、创建 RedisClient 客户端
            this.redisClient = RedisClient.create(uri);
    
            //3、获取连接
            this.connect = redisClient.connect();
        }
    
        //操作redis的命令
        public void accessRedis()
        {
            /*
             * 对于反应式API,由于测试时想要立即获取结果,因此需要使用bLock来阻塞线程,获取反应式方法的结果
             * 否则你的程序已经退出了,但反应式方法所返回的Mono或FLux 中数据还未到来。
             * 反应式返回的数据类型,都是 Mono 或者是 Flux 这两种而已。
             * block 就相当于在等 消息发布者Mono 发布数据,如果没有发布数据,就一直等,阻塞,相当于把反应式又变成了同步的数据读取方式
             * block():表示一定要取到值,一定要有数据 ;
             *
             * 如果前端结合WebFLux使用反应式API,就可以直接让控制器返回Mono或者FLuX,这样就不需要bLock了
             * 如果前端用的WEbFLux,后端用反应式api是很爽的,但如果前端用的是普通Spring MVC,那就不太理想了。
             */
    
            //4、创建反应式 RedisReactiveCommands ----------------使用反应式的方式来操作数据库
            RedisReactiveCommands cmd = connect.reactive();
    
            //通过redis的命令进行各种操作
    
            //添加一个string对象      返回值都一样是 Mono ,直接打印
            System.err.println(cmd.set("name", "ljh").block());
    
            //添加一个list对象
            System.err.println(cmd.lpush("schools", "小学", "中学", "大学").block());
    
            //添加一个set对象
            System.err.println(cmd.sadd("items", "电脑", "鼠标", "钱包").block());
    
            //添加zset对象,zset比set多一个score的分数功能,三种向zset对象添加元素的方法
            System.err.println(cmd.zadd("test", 3.0, "java").block());
            System.err.println(cmd.zadd("test", 3.2, "mysql", 3.5, "nosql").block());
            System.err.println(cmd.zadd("test", ScoredValue.just(2.1, "jsp")
                    , ScoredValue.just(2.2, "vue")).block());
    
            //添加一个hash对象
            System.err.println(cmd.hmset("user", Map.of("name", "aaa", "age", "20", "height", "170"))
                    .block());
        }
    
        //关闭资源
        public void closeResource()
        {
            connect.close();
            redisClient.shutdown();
        }
    
    
        public static void main(String[] args)
        {
            Reactive reactive = new Reactive();
            reactive.init();
            reactive.accessRedis();
            reactive.closeResource();
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97

    pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>cn.ljh</groupId>
        <artifactId>lettuceqs</artifactId>
        <version>1.0.0</version>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>8</source>
                        <target>8</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <!-- 引入 Lettuce 这个操作redis的框架的依赖 -->
            <dependency>
                <groupId>io.lettuce</groupId>
                <artifactId>lettuce-core</artifactId>
                <version>6.1.4.RELEASE</version>
            </dependency>
        </dependencies>
    
    </project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
  • 相关阅读:
    ps的一些快捷键
    C++11标准模板(STL)- 算法(std::reverse)
    nodejs的express负载均衡(续)
    faker.js 创建者希望 GitHub 恢复他的权利;微软公布 VS Code 2022 年路线图;Java 18 的新特性 | 开源日报
    使用 HelpLook Chatbot,让AI聊天机器人变成销售经理
    2022.8.8-8.14 AI行业周刊(第110期):值钱比赚钱更重要
    微信小程序自定义按钮触发转发分享功能
    React - 路由跳转方法
    Dapr v1.13 版本已发布
    【html】H1_基础
  • 原文地址:https://blog.csdn.net/weixin_44411039/article/details/133501459