【Redis学习】C++语言的Redis客户端使用方法

Redis学习笔记:

https://blog.csdn.net/2301_80220607/category_13051025.html?spm=1001.2014.3001.5482

前言:

我们前面使用Redis都是通过命令行的方式,在我们实际开发中这样当然是不行的,我们需要像使用mysql那样通过API接口来通过高级编程语言使用Redis,下面我们就学习一下如何使用C++语言的Redis客户端

我们下面是在linux环境下编程的,在进行下面操作前一定要记得先把环境配置好

1. 认识RESP

简单点来说,RESP就是Redis通信的应用层协议

在进行下面操作前,我们首先要认识到一点,为什么我们可以通过C++语言使用Redis?

我们说过Redis是类似于MySQL,在架构上分为客户端和服务端,服务端不需要我们去考虑,我们需要考虑的就是客户端,Redis在网络中很明显是属于应用层的部分,所以我们也不需要考虑应用层以下的部分,所以我们要想实现Redis客户端与服务端之间的通信,只需要设计好一套应用层协议,能够让客户端和服务端能够互相通信即可。

我们前面直接通过命令行操作Redis,实际上也是通过特定的Redis应用层协议进行通信的,它有点类似于http、https等应用层协议,如今我们要使用的C++语言的Redis客户端,实际上也是基于Redis的通信协议来进行相应的封装设计,从而使得我们可以通过C++编程创建一个Redis客户端来与Redis服务端进行通信

RESP就是redis官方自定义的通信协议,各种语言基于这个协议进行封装设计,从而设计出各种接口和库,从而非常方便的与Redis服务端建立通信

RESP的传输层是基于TCP协议的,当然,这不是我们要考虑的内容

2. Redis C++使用方法

首先需要先配置好环境,这样我们才能进行使用,我们需要包含指定头文件,所以我们可以查看系统路径下是否包含指定头文件来判断一下我们的环境是否配置成功

然后在写代码时首先要包含头文件

接下来我们就正式开始通过C++来使用Redis,首先我们是要先创建一个Redis对象,我们可以把这个Redis对象理解为一个接口,我们通过这个接口与一台指定的Redis服务器建立连接,并进行通信

sw::redis::Redis redis("tcp://127.0.0.1:6379");

这里的Redis类就是上面包含的头文件提供的

下面我们可以尝试进行一下ping操作来检验一下我们是否连接成功:

int main(){
    sw::redis::Redis redis("tcp://127.0.0.1:6379");
    //调用PING方法,客户端会给服务端发送一个PING请求,服务端收到请求后会返回一个PONG,收到了就代表我们连接成功
    string result=redis.ping();
    cout<<result<<endl;
    return 0;
}

当出现下面这种运行结果就代表我们连接成功:

下面我们就讲解以下C++如何通过redis对象来操作Redis,先来看一下几个通用命令

2.1 set 和 get

这两个指令的作用就是设置值和获取值,这里我们是封装了两个同名函数,通过对函数的操作来完成相应的指令动作

这里set中第一个参数的类型为 sw::redis::stringView ,我们可以把这个类型理解为只可读不可改的string类型

还有一个有趣的是get类型的返回值,get函数的返回值为optional, 这个类型可以用来表示两种形态,正确或者错误,正确时返回获取到的值,错误时返回的是redis中的空值nil

下面我们来看一下这两个函数具体如何使用:

void test1(sw::redis::Redis& redis){
    cout<<"set 和 get 的测试函数"<<endl;

    //先清空数据库,防止原数据库中有数据进行干扰
    redis.flushall();
    //这里set中第一个参数的类型为 sw::redis::stringView ,我们可以把这个类型理解为只可读不可改的string类型
    redis.set("key1","111");
    redis.set("key2","222");
    redis.set("key3","333");

    //get函数的返回值为optional, 这个类型可以用来表示两种形态,正确或者错误,正确时返回获取到的值,错误时返回的是redis中的空值nil
    auto value1=redis.get("key1");
    if(value1){
        cout<<"value1="<<value1.value()<<endl;
    }

    auto value2=redis.get("key2");
    if(value2){
        cout<<"value2="<<value2.value()<<endl;
    }

    auto value3=redis.get("key3");
    if(value1){
        cout<<"value3="<<value3.value()<<endl;
    }

    auto value4=redis.get("key4");
    if(value4){
        cout<<"value4="<<value4.value()<<endl;
    }
}
int main(){
    sw::redis::Redis redis("tcp://127.0.0.1:6379");
    test1(redis);
    return 0;
}

运行结果:

zwt@hcss-ecs-fd58:~/redis_study/cpp$ make
g++ -std=c++17 -g -O0 -o generic generic.cc /usr/local/lib/libredis++.a /lib/x86_64-linux-gnu/libhiredis.a -pthread
zwt@hcss-ecs-fd58:~/redis_study/cpp$ ./generic
set 和 get 的测试函数
value1=111
value2=222
value3=333

还有一个需要注意的是:

optional类型是不能直接进行<<输出的,因为类中没有重载这个运算符,需要借助value函数

2.2 exists 和 del

exists函数是用来判断存在的key的个数的,传参时可以传单个key,也可以通过列表传多个key,返回值类型是long long

del 函数的返回值是删除的key的个数,返回值类型是long long,传参时可以传单个key,也可以以列表方式传多个key

具体使用:

void test2(sw::redis::Redis& redis){
    cout<<"exists 和 del 测试函数"<<endl;
    redis.flushall();
    redis.set("key1","111");
    redis.set("key2","222");

    //exists 函数的返回值是存在的key的个数,返回值类型是long long,传参时可以传单个key,也可以以列表方式传多个key
    auto ret=redis.exists("key1");
    cout<<ret<<endl;
    ret=redis.exists("key3");
    cout<<ret<<endl;
    ret=redis.exists({"key1","key2","key3"});
    cout<<ret<<endl;

    //del 函数的返回值是删除的key的个数,返回值类型是long long,传参时可以传单个key,也可以以列表方式传多个key
    redis.set("key3","333");
    ret=redis.del({"key1","key2","key3"});
    cout<<ret<<endl;
}

运行结果:

zwt@hcss-ecs-fd58:~/redis_study/cpp$ make
g++ -std=c++17 -g -O0 -o generic generic.cc /usr/local/lib/libredis++.a /lib/x86_64-linux-gnu/libhiredis.a -pthread
zwt@hcss-ecs-fd58:~/redis_study/cpp$ ./generic
exists 和 del 测试函数
1
0
2
3

2.3 keys

keys函数最大的难点在于它传入的参数中需要有一个迭代器用来保存返回的结果,因为返回结果可能包含多个值,所以我们需要提前创建好一个容器来接收它,下面我们看一下具体如何操作:

void test3(sw::redis::Redis& redis){
    cout<<"keys 的测试函数"<<endl;
    redis.flushall();

    redis.set("key1","111");
    redis.set("key2","222");
    redis.set("key3","333");
    redis.set("key4","444");
    redis.set("key5","555");

    //keys 函数的第二个参数是一个“插入迭代器”,咱们需要先准备好一个保存结果的容器
    //接下来再创建一个插入迭代器指向容器的位置,这样就可以通过插入迭代器将 keys 获取的数据插入到容器的指定位置中去
    vector<string> result;
    auto it=std::back_inserter(result);
    redis.keys("*",it);
    printContainer(result);
}

运行结果:

2.4 expire 和 ttl

我们可以让程序休眠几秒,以此来看到ttl函数所获取的时间的真实性,但是为了程序在不同操作系统的可拓展性,我们不要用系统调用函数sleep,可以用线程库中的函数sleep_for

使用实例:

void test4(sw::redis::Redis& redis){
    using namespace std::chrono_literals;

    cout<<"expire 和 ttl 的测试函数"<<endl;
    redis.flushall();
    redis.set("key","111");
    redis.expire("key",std::chrono::seconds(10));

    //我们可以让程序休眠几秒,以此来看到ttl函数所获取的时间的真实性
    //但是为了程序在不同操作系统的可拓展性,我们不要用系统调用函数sleep,可以用线程库中的函数sleep_for
    std::this_thread::sleep_for(3s);

    auto time=redis.ttl("key");
    cout<<time<<endl;
}

运行结果:

2.5 type

type函数是用来查看指定的key对应的value类型的,这个比较简单,直接传入我们想查看的key就行

使用实例:

void test5(sw::redis::Redis& redis){
    cout<<"type 的测试函数"<<endl;
    redis.flushall();
    redis.set("key1","111");
    string result=redis.type("key1");
    cout<<"key1: "<<result<<endl;

    redis.lpush("key2","222");
    result=redis.type("key2");
    cout<<"key2: "<<result<<endl;

    redis.hset("key3","aaa","111");
    result=redis.type("key3");
    cout<<"key3: "<<result<<endl;

    redis.sadd("key4",{"aaa","bbb"});
    result=redis.type("key4");
    cout<<"key4: "<<result<<endl;

    redis.zadd("key5","吕布",99);
    result=redis.type("key5");
    cout<<"key5: "<<result<<endl;
}

运行结果:

2.5 总结

通过上面几个通用命令的讲解,我们可以发现使用C++通过调用函数的方式与我们直接使用命令所需的参数的个数等都是非常相似的,基本上我们使用命令要传什么,使用函数就也需要传什么,不同之处还是很少的,主要不同为以下几点:

  • 注意函数中引入的几种新的数据类型(StringView、optional...)
  • 当函数中可以传多个参数时,往往可以采用列表的方式进行传参
  • 当函数返回值可能有多个时,一般需要提前创建一个容器,并把容器迭代器传入函数中

C++连接Redis的所有函数都是遵循着上面的这几条规律,这里就不把所有函数进行讲解了,用到什么有问题了可以查一下官方文档


感谢各位大佬观看,创作不易,还望各位大佬点赞支持!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值