92、Redis ------- 使用 Lettuce 操作 Redis 数据库的方法、步骤 和 3种风格的操作redis数据库的演示(同步sync、异步async、反应式Reactive)


Redis ------- 使用 Lettuce 操作 Redis 数据库的方法、步骤 和 3种风格的操作redis数据库的演示(同步sync、异步async、反应式Reactive)

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

在这里插入图片描述


Lettuce的核心API

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

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

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

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


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:反应式

(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则是反应式版本


代码演示

先创建一个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();

    }
}














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();

    }
}

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();

    }
}

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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_L_J_H_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值