【Redis】Redis-plus-plus的安装与使用
目录
一.安装redis-plus-plus
1.1.安装hiredis
1.2.安装redis-plus-plus本体
1.3. 测试redis-plus-plus
二.使用通用命令
2.1.测试get/set
2.2.测试exists
2.3.测试del
2.4.测试keys
2.5.测试expire/ttl
2.6.测试type
三. 使用string的命令
3.1.测试get/set
3.2.测试mset/mget
3.3.测试getrange/setrange
3.4.测试incr和decr
四.使用list的命令
4.1.测试lpush和lrange
4.2.测试rpush和lrange
4.3.测试lpop和rpop
4.4.测试blpop
4.5.测试llen
五.使用set的命令
5.1.测试sadd,smembers
5.2.测试sismember
5.3.测试scard
5.4. 测试spop
5.5.测试sinter(交集)
5.6.测试sinterstore(存储交集)
六.使用hash的命令
6.1.测试hset和hget
6.2.测试hexists
6.3.测试hdel
6.4.测试hkeys 和 hvals
6.5.测试hmset和hmget
七. 使用zset的命令
7.1.测试zadd和zrange
7.2.测试zcard
7.3.测试zrem
7.4.测试zscore
7.5.测试zrank
八.访问集群
前面学习的主要是各种 redis 的基本操作/命令. 都是在 redis 命令行客户端, 手动执行的.
这种操作方式不是我们日常开发中主要的形式~~
更多的时候, 是使用 redis 的 api , 来实现定制化的 redis 客户端程序, 进一步操作 redis 服务器.
通过用程序来操作 redis ~~
以前学习 MySQL 的时候~ 也会涉及到, 关于使用程序来操作 MySQL 服务器
- C++: MySQL 原生 API
- Java: JDBC & MyBatis
redis 提供的命令行客户端 / 第三方的图形化客户端 ,他们本质上都属于是 "通用的客户端程序"
相比之下, 我们在工作中更希望使用到的是 "专用的" "定制化" 的客户端程序~~
是否前面学习的这些 redis 命令, 没有价值了呢??
当然不是的!!
redis 命令相当于使用代码来执行~~
一.安装redis-plus-plus
首先我们必须先安装cmake和g++
sudo apt update sudo apt install cmake sudo apt install g++
官网:GitHub - sewenew/redis-plus-plus: Redis client written in C++
1.1.安装hiredis
redis-plus-plus 是基于hiredis 实现的,hiredis 是⼀个C语⾔实现的redis客⼾端,因此需要先安装hiredis.。
由于 redis-plus-plus 是基于 hiredis,因此您应该先安装 hiredis。hiredis 的最低版本要求为 v0.12.1。
apt install libhiredis-dev
redis-plus-plus本体则用使用编译安装。如果是编译安装,则使用ubuntu安装比使用centos安装更简单。redis-plus-plus 是使用 CMAKE 构建的。 CMAKE是生成makefile的工具。我们得先安装CMAKE。
1.2.安装redis-plus-plus本体
好了,我们接下来来安装本体
git clone https://github.com/sewenew/redis-plus-plus.git
有的人可能下载不到啊,我们也可以去下载zip文件,然后再上传到我们的Linux服务器上
我们通过rz命令上传到Linux服务器里面来
然后解压一下
unzip redis-plus-plus-master.zip
解压之后,我们进去看看
接下来我们将
mkdir build
cd build
这里创建一个build目录是习惯做法,并非必须,目的是为了让编译产生的临时文件都放到build目录下,避免污染源代码目录。
cmake ..
我们看到生成了一些东西啊,这里就是makefile啊。接下来我们接着安装啊
make
这里就多了一些库啊!!
.a和.so都是当前编译的目录下,后续写代码的时候不一定能找到这里的库,所以我更推荐大家把这些库拷贝到系统目录里。不过这个我们不需要自己使用cp命令啥的去拷贝,我们直接执行下面这个命令就能进行拷贝到系统目录里面
sudo make install
这就把那些库拷贝到系统目录里面的。
这就安装完了,总的来说,就下面这些问题
好,现在就算是安装完成了,这个目录也没有存在的意义了,可以删除了。
我们这里也可以去看看我们拷贝到系统目录下的那些头文件和库文件
寻找头文件
我们得知道这个redis-plus-plus的头文件在哪里
ls -l /usr/local/include/sw/redis++/
这个redis++.h就是我们的核心头文件。
如果大家找不到在哪里,其实是可以使用find命令来查找
find /usr/ -name "redis++*"
由于/usr/local/include/是系统目录,所以我们在代码里面直接按照下面这样子写即可
#include<sw/redis++/redis++.h>
寻找静态库文件
find /usr/ -name "libredis*"
这也找到了!!!
1.3. 测试redis-plus-plus
我们先看看我们的端口号
接下来我们将使用redis-plus-plus来连接一下我们的redis服务器。
编程.cc文件
接下来我们就来创建一下文件
把下面这个内容填进去
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <sw/redis++/redis++.h>using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. sw::redis::Redis redis("tcp://127.0.0.1:6379");// 调用 ping 方法, 让客户端给服务器发了一个 PING, 然后服务器就会返回一个 PONG. 就通过 返回值 获取到. string result = redis.ping();std::cout << result << std::endl;return 0;
}
编写makefile
编写makefile的时候,需要引入库文件
- redis++自己的静态库
- hiredis的静态库
- 线程库
关键就是需要知道这些库的路径在哪里?
我们可以一个一个来找
- 寻找redis++自己的静态库
find /usr/ -name "libredis*"
这找到了!!!就是/usr/local/lib/libredis++.a
- 寻找hiredis的静态库
find /usr/ -name "libhiredis*"
找到了就是/usr/lib/x86_64-linux-gnu/libhiredis.a
- 线程库
这个都是我们的老朋友了,我们直接加一个-pthread即可
接下来我们写一下makefile,把下面这个填进去
hello:hello.ccg++ -std=c++17 -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread
.PHONY:clean
clean:rm hello
我们运行一下
这个PONG就是redis服务器返回的。
好,我们这个就是没有一点问题的!!!
现在就算是彻底安装成功了。
至于更多API,大家可以去:redis-plus-plus/src/sw/redis++/redis.h at master · sewenew/redis-plus-plus · GitHub
如果那个访问不了的话,也可以去:src/sw/redis++/redis.h · peixinchen/redis-plus-plus - Gitee.com
二.使用通用命令
我们接下来将好好的讲解一下,如何使用redis-plus-plus去执行我们之前介绍的通用命令
- get/set
- exists
- del
- keys
- expire/ttl
- type
接下来我们将创建一个test.cc,makefile
makefile的内容都是一样的,我在这里先给你们列出来,后面我就不说了
makefile
test:test.ccg++ -std=c++17 -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread
.PHONY:clean
clean:rm test
2.1.测试get/set
test.cc(第一版)
#include <iostream>
#include <string>
#include <sw/redis++/redis++.h>
using namespace std;// get 和 set
void test1(sw::redis::Redis& redis) {std::cout << "get 和 set 的使用" << std::endl;// 清空一下数据库, 避免之前残留的数据有干扰. redis.flushall();//注意这里删除了所有东西// 使用 set 设置 key//这个和之前的set命令的选项有很大的关联关系redis.set("key1", "111");redis.set("key2", "222");redis.set("key3", "333");// 使用 get 获取到 key1 对应的 valueauto value1 = redis.get("key1");std::cout << "value1=" << value1 << std::endl;auto value2 = redis.get("key2");std::cout << "value2=" << value2 << std::endl;auto value3 = redis.get("key3");std::cout << "value3=" << value3 << std::endl;auto value4 = redis.get("key4");std::cout << "value4=" << value4 << std::endl;
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. sw::redis::Redis redis("tcp://127.0.0.1:6379");test1(redis);return 0;
}
一编译,我们就发现报错了
这个是因为说明我们上面value1,value2,value3,value4不支持使用<<运算符。
此处不需要给这个 optional 搞一个 << 的重载, 没必要. 只需要把 optional 里面包含的元素给取出来就可以了~~ (optional 可以当做只包含一个元素的容器)
实际上我们只需将value1,value2,value3,value4全部换成下面这样子即可
- value1.value()
- value2.value()
- value3.value()
- value4.value()
test.cc(第二版)
#include <iostream>
#include <string>
#include <sw/redis++/redis++.h>
using namespace std;// get 和 set
void test1(sw::redis::Redis& redis) {std::cout << "get 和 set 的使用" << std::endl;// 清空一下数据库, 避免之前残留的数据有干扰. redis.flushall();//注意这里删除了所有东西// 使用 set 设置 key//这个和之前的set命令的选项有很大的关联关系redis.set("key1", "111");redis.set("key2", "222");redis.set("key3", "333");// 使用 get 获取到 key1 对应的 valueauto value1 = redis.get("key1");std::cout << "value1=" << value1.value() << std::endl;auto value2 = redis.get("key2");std::cout << "value2=" << value2.value() << std::endl;auto value3 = redis.get("key3");std::cout << "value3=" << value3.value() << std::endl;auto value4 = redis.get("key4");std::cout << "value4=" << value4.value() << std::endl;
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. sw::redis::Redis redis("tcp://127.0.0.1:6379");test1(redis);return 0;
}
编译运行一下:
我们发现还是有一点小问题的。
key4是不存在的,我们得到的value4是一个optional的非法状态,我们不能对其进行取值操作,这是未定义的行为,就会抛出异常。
为了避免这个清空,我们需要进行条件判断
test.cc(最终版本)
#include <iostream>
#include <string>
#include <sw/redis++/redis++.h>
using namespace std;// get 和 set
void test1(sw::redis::Redis& redis) {std::cout << "get 和 set 的使用" << std::endl;// 清空一下数据库, 避免之前残留的数据有干扰. redis.flushall();// 使用 set 设置 keyredis.set("key1", "111");redis.set("key2", "222");redis.set("key3", "333");// 使用 get 获取到 key 对应的 valueauto value1 = redis.get("key1");// optional 可以隐式转成 bool 类型, 可以直接在 if 中判定. 如果是无效元素, 就是返回 falseif (value1) {std::cout << "value1=" << value1.value() << std::endl;}auto value2 = redis.get("key2");if (value2) {std::cout << "value2=" << value2.value() << std::endl;}auto value3 = redis.get("key3");if (value3) {std::cout << "value3=" << value3.value() << std::endl;}auto value4 = redis.get("key4");if (value4) {std::cout << "value4=" << value4.value() << std::endl;}
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. sw::redis::Redis redis("tcp://127.0.0.1:6379");test1(redis);return 0;
}
我们编译运行一下:
现在就没有问题了
2.2.测试exists
这个很简单,我们直接看代码
test.cc
#include <iostream>
#include <string>
#include <sw/redis++/redis++.h>
using namespace std;//exist
void test2(sw::redis::Redis& redis) {std::cout << "exists" << std::endl;redis.flushall();redis.set("key", "111");redis.set("key3", "111");auto ret = redis.exists("key");std::cout << ret << std::endl;ret = redis.exists("key2");std::cout << ret << std::endl;//一次性测试多个keyret = redis.exists({"key", "key2", "key3"});std::cout << ret << std::endl;
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. sw::redis::Redis redis("tcp://127.0.0.1:6379");test2(redis);return 0;
}
编译运行结果如下:
2.3.测试del
这个很简单
test.cc
#include <iostream>
#include <string>
#include <sw/redis++/redis++.h>
using namespace std;void test3(sw::redis::Redis& redis) {std::cout << "del" << std::endl;// 清除库非常必要的! redis.flushall();redis.set("key", "111");redis.set("key2", "111");// redis.del("key");auto ret = redis.del({"key", "key2", "key3"});std::cout << ret << std::endl;ret = redis.exists({"key", "key2"});std::cout << ret << std::endl;
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. sw::redis::Redis redis("tcp://127.0.0.1:6379");test3(redis);return 0;
}
2.4.测试keys
这里可是返回多个值
test.cc
#include <iostream>
#include <string>
#include <sw/redis++/redis++.h>
using namespace std;template<typename T>
inline void printContainer(const T& container) {for (const auto& elem : container) {std::cout << elem << std::endl;}
}void test4(sw::redis::Redis& redis) {std::cout << "keys" << std::endl;redis.flushall();redis.set("key", "111");redis.set("key2", "222");redis.set("key3", "333");redis.set("key4", "444");redis.set("key5", "555");redis.set("key6", "666");// keys 的第二个参数, 是一个 "插入迭代器". 咱们需要先准备好一个保存结果的容器. // 接下来再创建一个插入迭代器指向容器的位置. 就可以把 keys 获取到的结果依次通过刚才的插入迭代器插入到容器的指定位置中了. vector<string> result;auto it = std::back_inserter(result);redis.keys("*", it);printContainer(result);
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. sw::redis::Redis redis("tcp://127.0.0.1:6379");test4(redis);return 0;
}
我们这里需要讲解一下STL中的五种迭代器的类型
- 输入迭代器
- 输出迭代器
- 前向迭代器
- 双向迭代器
- 随机访问迭代器
2.5.测试expire/ttl
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
using namespace std;void test5(sw::redis::Redis& redis) {using namespace std::chrono_literals;std::cout << "expire and ttl" << std::endl;redis.flushall();redis.set("key", "111");// 10s => std::chrono::seconds(10)redis.expire("key", 10s);//设置了过期时间std::this_thread::sleep_for(1s);auto time = redis.ttl("key");//查看过期时间std::cout << time << std::endl;std::this_thread::sleep_for(1s);time = redis.ttl("key");//查看过期时间std::cout << time << std::endl;std::this_thread::sleep_for(8s);time = redis.ttl("key");//查看过期时间std::cout << time << std::endl;
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. sw::redis::Redis redis("tcp://127.0.0.1:6379");test5(redis);return 0;
}
2.6.测试type
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
using namespace std;void test6(sw::redis::Redis& redis) {std::cout << "type" << std::endl;redis.flushall();redis.set("key", "111");string result = redis.type("key");std::cout << "key: " << result << std::endl;redis.lpush("key2", "111");result = redis.type("key2");std::cout << "key2: " << result << std::endl;redis.hset("key3", "aaa", "111");result = redis.type("key3");std::cout << "key3: " << result << std::endl;redis.sadd("key4", "aaa");result = redis.type("key4");std::cout << "key4: " << result << std::endl;redis.zadd("key5", "吕布", 99);result = redis.type("key5");std::cout << "key5: " << result << std::endl;
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. sw::redis::Redis redis("tcp://127.0.0.1:6379");test6(redis);return 0;
}
怎么样?学到现在,是不是和我们之前学习的命令是一模一样的。
三. 使用string的命令
接下来我们还是沿用上面的makefile
makefile的内容都是一样的,我在这里先给你们列出来,后面我就不说了
makefile
test:test.ccg++ -std=c++17 -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread
.PHONY:clean
clean:rm test
3.1.测试get/set
test.cc(普通版本)
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
using namespace std;
using sw::redis::Redis;void test1(Redis& redis) {std::cout << "get 和 set" << std::endl;redis.flushall();redis.set("key", "111");auto value = redis.get("key");if (value) {std::cout << "value: " << value.value() << std::endl;}redis.set("key", "222");value = redis.get("key");if (value) {std::cout << "value: " << value.value() << std::endl;}
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test1(redis);return 0;
}
test.cc(测试带有超时时间的)
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
using namespace std;
using sw::redis::Redis;void test2(Redis& redis) {std::cout << "set 带有超时时间" << std::endl;redis.flushall();redis.set("key", "111", 10s);std::this_thread::sleep_for(3s);long long time = redis.ttl("key");std::cout << "time: " << time << std::endl;std::this_thread::sleep_for(7s);time = redis.ttl("key");std::cout << "time: " << time << std::endl;
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test2(redis);return 0;
}
测试NX,XX(第一版)
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
using namespace std;
using sw::redis::Redis;void test3(Redis& redis) {std::cout << "set NX 和 XX" << std::endl;redis.flushall();// set 的重载版本中, 没有单独提供 NX 和 XX 的版本, 必须搭配过期时间的版本来使用. redis.set("key", "111", 0s, sw::redis::UpdateType::NOT_EXIST);//相当于带NX选项的SETauto value = redis.get("key");if (value) {std::cout << "value: " << value.value() << std::endl;} else {std::cout << "key 不存在!" << std::endl;}redis.set("key", "222", 0s, sw::redis::UpdateType::EXIST);//相当于带XX选项的SETvalue = redis.get("key");if (value) {std::cout << "value: " << value.value() << std::endl;} else {std::cout << "key 不存在!" << std::endl;}
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test3(redis);return 0;
}
完全没有什么问题。
这样子其实还是看不太出来,我们可以调换一下NX和XX的位置
测试NX,XX(第二版)
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
using namespace std;
using sw::redis::Redis;void test3(Redis& redis) {std::cout << "set NX 和 XX" << std::endl;redis.flushall();// set 的重载版本中, 没有单独提供 NX 和 XX 的版本, 必须搭配过期时间的版本来使用. redis.set("key", "111", 0s, sw::redis::UpdateType::EXIST);//相当于带XX选项的SETauto value = redis.get("key");if (value) {std::cout << "value: " << value.value() << std::endl;} else {std::cout << "key 不存在!" << std::endl;}redis.set("key", "222", 0s, sw::redis::UpdateType::NOT_EXIST);//相当于带NX选项的SETvalue = redis.get("key");if (value) {std::cout << "value: " << value.value() << std::endl;} else {std::cout << "key 不存在!" << std::endl;}
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test3(redis);return 0;
}
怎么样?这样子就很明白了吧!!
3.2.测试mset/mget
test.cc(测试mset)
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
using namespace std;
using sw::redis::Redis;void test4(Redis& redis) {std::cout << "mset" << std::endl;redis.flushall();// 第一种写法, 使用初始化列表描述多个键值对// redis.mset({ std::make_pair("key1", "111"), std::make_pair("key2", "222"), std::make_pair("key3", "333") });// 第二种写法, 可以把多个键值对提前组织到容器中. 以迭代器的形式告诉 msetvector<std::pair<string, string>> keys = {{"key1", "111"},{"key2", "222"},{"key3", "333"}};redis.mset(keys.begin(), keys.end());auto value = redis.get("key1");if (value) {std::cout << "value: " << value.value() << std::endl;}value = redis.get("key2");if (value) {std::cout << "value: " << value.value() << std::endl;}value = redis.get("key3");if (value) {std::cout << "value: " << value.value() << std::endl;}
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test4(redis);return 0;
}
test.cc(测试mget)
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
using namespace std;
using sw::redis::Redis;template<typename T>
inline void printContainerOptional(const T& container) {for (const auto& elem : container) {// 此处预期 elem 是一个 optional 类型的元素, 打印之前, 先判定一下, 看是否有效if (elem) {std::cout << elem.value() << std::endl;} else {std::cout << "元素无效" << std::endl;}}
}void test5(Redis& redis) {std::cout << "mget" << std::endl;redis.flushall();vector<std::pair<string, string>> keys = {{"key1", "111"},{"key2", "222"},{"key3", "333"}};redis.mset(keys.begin(), keys.end());vector<sw::redis::OptionalString> result;auto it = std::back_inserter(result);redis.mget({"key1", "key2", "key3", "key4"}, it);printContainerOptional(result);
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test5(redis);return 0;
}
3.3.测试getrange/setrange
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
using namespace std;
using sw::redis::Redis;void test6(Redis& redis) {std::cout << "getrange 和 setrange" << std::endl;redis.flushall();redis.set("key", "abcdefghijk");// 使用getrange获取子字符串:从索引2开始到索引5结束(包含两端)// Redis字符串索引从0开始,2->'c', 5->'f',结果应为"cdef"string result = redis.getrange("key", 2, 5);std::cout << "result: " << result << std::endl; // 预期输出:cdef// 使用setrange修改字符串:从索引2开始覆盖写入"xyz"// 原始值:abcdefghijk// 修改后:abxyzfghijk(索引2位置开始替换3个字符)redis.setrange("key", 2, "xyz");// 获取修改后的完整值auto value = redis.get("key");// 使用.value()安全访问optional值(需确保值存在)std::cout << "value: " << value.value() << std::endl; // 预期输出:abxyzfghijk
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test6(redis);return 0;
}
3.4.测试incr和decr
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
using namespace std;
using sw::redis::Redis;void test7(Redis& redis) {std::cout << "incr 和 decr" << std::endl;redis.flushall();redis.set("key", "100");long long result = redis.incr("key");std::cout << "result: " << result << std::endl;auto value = redis.get("key");std::cout << "value: " << value.value() << std::endl;result = redis.decr("key");std::cout << "result: " << result << std::endl;value = redis.get("key");std::cout << "value: " << value.value() << std::endl;
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test7(redis);return 0;
}
四.使用list的命令
4.1.测试lpush和lrange
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
using namespace std;
using sw::redis::Redis;template<typename T>
inline void printContainer(const T& container) {for (const auto& elem : container) {std::cout << elem << std::endl;}
}void test1(Redis& redis) {std::cout << "lpush 和 lrange" << std::endl;redis.flushall();// 插入单个元素redis.lpush("key", "111");// 插入一组元素, 基于初始化列表redis.lpush("key", {"222", "333", "444"});// 插入一组元素, 基于迭代器vector<string> values = {"555", "666", "777"};redis.lpush("key", values.begin(), values.end());// lrange 获取到列表中的元素vector<string> results;auto it = std::back_inserter(results);redis.lrange("key", 0, -1, it);printContainer(results);
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test1(redis);return 0;
}
4.2.测试rpush和lrange
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
using namespace std;
using sw::redis::Redis;template<typename T>
inline void printContainer(const T& container) {for (const auto& elem : container) {std::cout << elem << std::endl;}
}void test2(Redis& redis) {std::cout << "rpush" << std::endl;redis.flushall();// 插入单个元素redis.rpush("key", "111");// 插入多个元素, 基于初始化列表redis.rpush("key", {"222", "333", "444"});// 插入多个元素, 基于容器vector<string> values = {"555", "666", "777"};redis.rpush("key", values.begin(), values.end());// 使用 lrange 获取元素vector<string> results;auto it = std::back_inserter(results);redis.lrange("key", 0, -1, it);printContainer(results);
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test2(redis);return 0;
}
4.3.测试lpop和rpop
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
using namespace std;
using sw::redis::Redis;void test3(Redis& redis) {std::cout << "lpop 和 rpop" << std::endl;redis.flushall();// 构造一个 listredis.rpush("key", {"1", "2", "3", "4"});auto result = redis.lpop("key");if (result) {std::cout << "lpop: " << result.value() << std::endl;}result = redis.rpop("key");if (result) {std::cout << "rpop: " << result.value() << std::endl;}
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test3(redis);return 0;
}
4.4.测试blpop
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
using namespace std;
using sw::redis::Redis;void test4(Redis& redis) {using namespace std::chrono_literals;std::cout << "blpop" << std::endl;redis.flushall();auto result = redis.blpop({"key", "key2", "key3"}, 10s);if (result) {std::cout << "key:" << result->first << std::endl;std::cout << "elem:" << result->second << std::endl;} else {std::cout << "result 无效!" << std::endl;}
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test4(redis);return 0;
}
等待10秒之后
4.5.测试llen
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
using namespace std;
using sw::redis::Redis;void test5(Redis& redis) {std::cout << "llen" << std::endl;redis.flushall();redis.lpush("key", {"111", "222", "333", "444"});long long len = redis.llen("key");std::cout << "len: " << len << std::endl;
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test5(redis);return 0;
}
五.使用set的命令
5.1.测试sadd,smembers
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
#include<set>
using namespace std;
using sw::redis::Redis;template<typename T>
inline void printContainer(const T& container) {for (const auto& elem : container) {std::cout << elem << std::endl;}
}void test1(Redis& redis) {std::cout << "sadd 和 smembers" << std::endl;redis.flushall();// 一次添加一个元素redis.sadd("key", "111");// 一次添加多个元素(使用初始化列表)redis.sadd("key", {"222", "333", "444"});// 一次添加多个元素(使用迭代器)set<string> elems = {"555", "666", "777"};redis.sadd("key", elems.begin(), elems.end());// 获取到上述元素// 此处用来保存 smembers 的结果, 使用 set 可能更合适. vector<string> result;// auto it = std::back_inserter(result);// 由于此处 set 里的元素顺序是固定的. 指定一个 result.end() 或者 result.begin() 或者其他位置的迭代器, 都无所谓~~auto it = std::inserter(result, result.end());redis.smembers("key", it);printContainer(result);
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test1(redis);return 0;
}
5.2.测试sismember
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
#include<set>
using namespace std;
using sw::redis::Redis;void test2(Redis& redis) {std::cout << "sismember" << std::endl;redis.flushall();redis.sadd("key", {"111", "222", "333", "444"});bool result = redis.sismember("key", "222");std::cout << "222: " << result << std::endl;result = redis.sismember("key", "555");std::cout << "555: " << result << std::endl;
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test2(redis);return 0;
}
5.3.测试scard
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
#include<set>
using namespace std;
using sw::redis::Redis;void test3(Redis& redis) {std::cout << "scard" << std::endl;redis.flushall();redis.sadd("key", {"111", "222", "333"});long long result = redis.scard("key");std::cout << "result: " << result << std::endl;
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test3(redis);return 0;
}
5.4. 测试spop
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
#include<set>
using namespace std;
using sw::redis::Redis;void test4(Redis& redis) {std::cout << "spop" << std::endl;redis.flushall();redis.sadd("key", {"111", "222", "333", "444"});auto result = redis.spop("key");if (result) {std::cout << "result: " << result.value() << std::endl;} else {std::cout << "result 无效!" << std::endl;}
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test4(redis);return 0;
}
5.5.测试sinter(交集)
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
#include<set>
using namespace std;
using sw::redis::Redis;template<typename T>
inline void printContainer(const T& container) {for (const auto& elem : container) {std::cout << elem << std::endl;}
}void test5(Redis& redis) {std::cout << "sinter" << std::endl;redis.flushall();redis.sadd("key1", {"111", "222", "333"});redis.sadd("key2", {"111", "222", "444"});set<string> result;auto it = std::inserter(result, result.end());redis.sinter({"key1", "key2"}, it);printContainer(result);
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test5(redis);return 0;
}
5.6.测试sinterstore(存储交集)
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
#include<set>
using namespace std;
using sw::redis::Redis;template<typename T>
inline void printContainer(const T& container) {for (const auto& elem : container) {std::cout << elem << std::endl;}
}void test6(Redis& redis) {std::cout << "sinterstore" << std::endl;redis.flushall();redis.sadd("key1", {"111", "222", "333"});redis.sadd("key2", {"111", "222", "444"});long long len = redis.sinterstore("key3", {"key1", "key2"});std::cout << "len: " << len << std::endl;set<string> result;auto it = std::inserter(result, result.end());redis.smembers("key3", it);printContainer(result);
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test6(redis);return 0;
}
六.使用hash的命令
6.1.测试hset和hget
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
#include<set>
using namespace std;
using sw::redis::Redis;void test1(Redis& redis) {std::cout << "hset 和 hget" << std::endl;redis.flushall();redis.hset("key", "f1", "111");redis.hset("key", std::make_pair("f2", "222"));// hset 能够一次性插入多个 field-value 对!!redis.hset("key", {std::make_pair("f3", "333"),std::make_pair("f4", "444")});vector<std::pair<string, string>> fields = {std::make_pair("f5", "555"),std::make_pair("f6", "666")};redis.hset("key", fields.begin(), fields.end());auto result = redis.hget("key", "f3");if (result) {std::cout << "result: " << result.value() << std::endl;} else {std::cout << "result 无效!" << std::endl;}
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test1(redis);return 0;
}
6.2.测试hexists
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
#include<set>
using namespace std;
using sw::redis::Redis;void test2(Redis& redis) {std::cout << "hexits" << std::endl;redis.flushall();redis.hset("key", "f1", "111");redis.hset("key", "f2", "222");redis.hset("key", "f3", "333");bool result = redis.hexists("key", "f1");std::cout << "f1: " << result << std::endl;result = redis.hexists("key", "f4");std::cout << "f4: " << result << std::endl;
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test2(redis);return 0;
}
6.3.测试hdel
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
#include<set>
using namespace std;
using sw::redis::Redis;void test3(Redis& redis) {std::cout << "hdel" << std::endl;redis.flushall();redis.hset("key", "f1", "111");redis.hset("key", "f2", "222");redis.hset("key", "f3", "333");long long result = redis.hdel("key", "f1");std::cout << "result: " << result << std::endl;long long len = redis.hlen("key");std::cout << "len: " << len << std::endl;result = redis.hdel("key", {"f2", "f3"});std::cout << "result: " << result << std::endl;len = redis.hlen("key");std::cout << "len: " << len << std::endl;
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test3(redis);return 0;
}
6.4.测试hkeys 和 hvals
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
#include<set>
using namespace std;
using sw::redis::Redis;template<typename T>
inline void printContainer(const T& container) {for (const auto& elem : container) {std::cout << elem << std::endl;}
}void test4(Redis& redis) {std::cout << "hkeys 和 hvals" << std::endl;redis.flushall();redis.hset("key", "f1", "111");redis.hset("key", "f2", "222");redis.hset("key", "f3", "333");vector<string> fields;auto itFields = std::back_inserter(fields);redis.hkeys("key", itFields);printContainer(fields);vector<string> values;auto itValues = std::back_inserter(values);redis.hvals("key", itValues);printContainer(values);
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test4(redis);return 0;
}
6.5.测试hmset和hmget
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
#include<set>
using namespace std;
using sw::redis::Redis;template<typename T>
inline void printContainer(const T& container) {for (const auto& elem : container) {std::cout << elem << std::endl;}
}void test5(Redis& redis) {std::cout << "hmget 和 hmset" << std::endl;redis.flushall();redis.hmset("key", {std::make_pair("f1", "111"),std::make_pair("f2", "222"),std::make_pair("f3", "333")});vector<std::pair<string, string>> pairs = {std::make_pair("f4", "444"),std::make_pair("f5", "555"),std::make_pair("f6", "666")};redis.hmset("key", pairs.begin(), pairs.end());vector<string> values;auto it = std::back_inserter(values);redis.hmget("key", {"f1", "f2", "f3"}, it);printContainer(values);
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test5(redis);return 0;
}
七. 使用zset的命令
7.1.测试zadd和zrange
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
#include<set>
using namespace std;
using sw::redis::Redis;template<typename T>
inline void printContainer(const T& container) {for (const auto& elem : container) {std::cout << elem << std::endl;}
}template<typename T>
inline void printContainerPair(const T& container) {for (auto& elem : container) {// 此处预期 elem 是一个 std::pairstd::cout << elem.first << ": " << elem.second << std::endl;}
}void test1(Redis& redis) {std::cout << "zadd 和 zrange" << std::endl;redis.flushall();redis.zadd("key", "吕布", 99);redis.zadd("key", {std::make_pair("赵云", 98),std::make_pair("典韦", 97)});vector<std::pair<string, double>> members = {std::make_pair("关羽", 95),std::make_pair("张飞", 93)};redis.zadd("key", members.begin(), members.end());// zrange 支持两种主要的风格:// 1. 只查询 member, 不带 score// 2. 查询 member 同时带 score// 关键就是看插入迭代器指向的容器的类型. // 指向的容器只是包含一个 string, 就是只查询 member// 指向的容器包含的是一个 pair, 里面有 string 和 double, 就是查询 member 同时带有 scorevector<string> memberResults;auto it = std::back_inserter(memberResults);redis.zrange("key", 0, -1, it);printContainer(memberResults);vector<std::pair<string, double>> membersWithScore;auto it2 = std::back_inserter(membersWithScore);redis.zrange("key", 0, -1, it2);printContainerPair(membersWithScore);
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test1(redis);return 0;
}
7.2.测试zcard
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
#include<set>
using namespace std;
using sw::redis::Redis;void test2(Redis& redis) {std::cout << "zcard" << std::endl;redis.flushall();redis.zadd("key", "zhangsan", 90);redis.zadd("key", "lisi", 91);redis.zadd("key", "wangwu", 92);redis.zadd("key", "zhaoliu", 93);long long result = redis.zcard("key");std::cout << "result: " << result << std::endl;
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test2(redis);return 0;
}
7.3.测试zrem
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
#include<set>
using namespace std;
using sw::redis::Redis;void test3(Redis& redis) {std::cout << "zrem" << std::endl;redis.flushall();redis.zadd("key", "zhangsan", 90);redis.zadd("key", "lisi", 91);redis.zadd("key", "wangwu", 92);redis.zadd("key", "zhaoliu", 93);redis.zrem("key", "zhangsan");long long result = redis.zcard("key");std::cout << "result: " << result << std::endl;
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test3(redis);return 0;
}
7.4.测试zscore
test.cc
#include <iostream>
#include <string>
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
#include<set>
using namespace std;
using sw::redis::Redis;void test4(Redis& redis) {std::cout << "zscore" << std::endl;redis.flushall();redis.zadd("key", "zhangsan", 90);redis.zadd("key", "lisi", 91);redis.zadd("key", "wangwu", 92);redis.zadd("key", "zhaoliu", 93);auto score = redis.zscore("key", "zhangsan");if (score) {std::cout << "score: " << score.value() << std::endl;} else {std::cout << "score 无效" << std::endl;}
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test4(redis);return 0;
}
7.5.测试zrank
test.cc
#include <thread>
#include<chrono>
#include <sw/redis++/redis++.h>
#include<set>
using namespace std;
using sw::redis::Redis;void test5(Redis& redis) {std::cout << "zrank" << std::endl;redis.flushall();redis.zadd("key", "zhangsan", 90);redis.zadd("key", "lisi", 91);redis.zadd("key", "wangwu", 92);redis.zadd("key", "zhaoliu", 93);auto rank = redis.zrank("key", "zhaoliu");if (rank) {std::cout << "rank: " << rank.value() << std::endl;} else {std::cout << "rank 无效" << std::endl;}
}int main() {// 创建 Redis 对象的时候, 需要在构造函数中, 指定 redis 服务器的地址和端口. Redis redis("tcp://127.0.0.1:6379");test5(redis);return 0;
}
八.访问集群
只需要使⽤ RedisCluster 类代替 Redis 类即可.
构造⽅法中填⼊集群中的任意节点地址.
RedisCluster 提供了和 Redis 类⼀样的接⼝,基本都和Redis原⽣命令⼀致
#include <sw/redis++/redis++.h>#include <cstdio>#include <string>#include <vector>using std::string;using sw::redis::RedisCluster;using sw::redis::OptionalString;int main() {RedisCluster cluster("tcp://127.0.0.1:6379");cluster.set("k1", "111");auto value = cluster.get("k1");printf("value: %s\n", value->c_str());return 0;}