当前位置: 首页 > article >正文

【redis初阶】redis客户端

目录

一、基本介绍

二、认识RESP(redis自定的应用层协议名称)

三、访问github的技巧

四、安装redisplusplus

4.1 安装 hiredis**

4.2 下载 redis-plus-plus 源码

4.3 编译/安装 redis-plus-plus

五、编写运行helloworld

六、redis命令演示

6.1 通用命令的使用

6.2 string的使用

6.3 list的使用

6.4 set的使用

6.5 hash的使用

6.6 zset的使用


redis学习🥳

一、基本介绍

在前面的学习中主要是学习 redis 的各种基本操作/命令,都是在 redis 命令行客户端中手动执行 redis各种命令,但这种操作方式不是我们日常开发中的主要形式;更多的时候,我们是使用 redis 的 api 来实现定制化的 redis 客户端程序,进一步操作 redis 服务器;

不管是 redis 提供的命令行客户端,还是第三方的图形化客户端,他们本质上都属于是“通用的客户端程序”。但相比之下,我们在工作中更希望使用到的是“专用的”“定制化”的客户端程序;

二、认识RESP(redis自定的应用层协议名称)

我们为什么能编写出一个自定义的redis客户端呢?

我们知道在网络通信过程中,会使用到很多的“协议”

应用层往下的协议是固定好的,是在系统内核或者驱动程序中实现的,我们是不可修改的,但是对于应用层来说,虽然业界有很多成熟的应用层协议,比如 http 等,但是此处更多的时候,都会“自定义”应用层协议,redis 此处应用层协议,就是自定义的应用层协议,客户端按照 resp 协议发送请求,服务器按照这个协议进行解析,在按照这个协议构造响应,客户端在解析这个响应,完成客户端和服务器的通信;

因此:resp 就是 redis 自定义的客户端和服务器用于通信的应用层协议;

resp协议特点:

  • 简单好实现;
  • 快速进行解析;
  • 肉眼可读;
  • 基于传输层的tcp,但是与tcp又没有强耦合;
  • 请求和响应之间的通信是一问一答的形式(客户端给服务器发起一个请求,服务器返回一个响应);
  • 客户端给redis服务器发送命令时:是以bulk string数组的形式发送的redis命令,对于不同的redis命令,服务器返回的结果是不一样的(ok、整个数组...);

在RESP中,第一个字节决定了数据类型:

  • 对于Simple Strings,回复的第一个字节是“+” eg:"+OK\r\n"
  • 对于Errors,回复的第一个字节是“-”   eg:"-Error message\r\n"
  • 对于Integers,回复的第一个字节是“:”   eg:":1000\r\n"
  • 对于Bulk Strings,回复的第一个字节是“$”   eg:"$5\r\nhello\r\n"
  • 对于Arrays,回复的第一个字节是“*”   eg:"*2\r\n$5\r\nhello\r\n$5\r\nworld\r\n"

在进行通信的时候,服务器就把构造好的字符串,写入到 tcp socket 中;

Simple Strings 和 Bulk Strings 的区别:Simple String 只能用来传输文本,Bulk String 可以传输二进制数据;

上述这套协议公开已久,已经有很多大佬,实现了这套协议的解析/构造,在写代码的时候,我们不需要按照上述的协议,解析/构造字符串,只要使用这些大佬们提供的库,就可以比较简单方便的来完成和 redis 服务器通信的操作了;

三、访问github的技巧

翻墙 or 下载游戏加速器,推荐:watt toolkit

选中gitup,一键加速

四、安装redisplusplus

C++ 操作 redis 的库有很多,咱们此处使用 redis-plus-plus.

这个库的功能强大,使用简单.

Github 地址:  https://github.com/sewenew/redis-plus-plus

4.1 安装 hiredis**

redis-plus-plus 是基于 hiredis 实现的.

hiredis 是一个 C 语言实现的 redis 客户端.

因此需要先安装 hiredis. 直接使用包管理器安装即可.

在 Ubuntu 镜像下:

apt install libhiredis-dev

4.2 下载 redis-plus-plus 源码

git clone https://github.com/sewenew/redis-plus-plus.git

4.3 编译/安装 redis-plus-plus

redis-plus-plus 是使用 cmake 构建工具进行构建的,cmake 相当于是 Makefile 的升级版,Makefile 本身功能比较简陋,比较原始,写起来也比较麻烦实际开发中很少会手写 makefile,cmake 就是通过程序来生成 makefile 的 工具;

在 Ubuntu 镜像下:

使用 cmake 构建:

cd redis-plus-plus

# 创建一个 build 目录是习惯做法,并非必须。目的是为了让编译生成的临时文件都放到 build 下,避免污染源代码目录
mkdir build
cd build

# 这个操作是生成makefile,此处..指向的是刚才 CMakeLits.txt 文件所在的目录
cmake3 ..

make    # 进行编译
sudo make install # 将编译生成的 .a .so 等系列库拷贝到系统目录

make 后结果:

make install 后结果:

构建成功后,会在 /usr/local/include/ 中多出 sw 目录,并且内部包含 redis-plus-plus 的一系列头文件;

会在 /usr/local/lib/ 中多出一系列 libredis 库文件.

五、编写运行helloworld

创建代码目录:

编写 hello.cpp 文件:

#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();
    cout << result << endl;
}

编写 makefile 文件:

hello:hello.cpp
    g++ -std=c++17 -o $@ $^ /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -pthread

    # /usr/local/lib/libredis++.a               redis自己的静态库
    # /usr/lib/x86_64-linux-gnu/libhiredis.a    hiredis的静态库
    # -pthread                                    线程库

.PHONY:clean
clean:
    rm hello

编译运行:

六、redis命令演示

工具文件:

util.hpp 文件:

# pragma once

# include <iostream>
# include <vector>
#include <string>

// 打印容器内元素
template<typename T>
inline void printContainer(const T& container) {
    for(const auto& elem : container) {
        std::cout << elem << std::endl;
    }
}

// 当容器内元素是 pair 类型时,打印容器内元素
template<typename T>
inline void printContainerPair(const T& container) {
    for(const auto& elem : container) {
        std::cout << elem.first << " : " << elem.second << std::endl;
    }
}

// 当容器内元素是 optional 类型时,打印容器内元素
template<typename T>
inline void printContainerOptional(const T& container) {
    for(const auto& elem : container) {
        if(elem) {
            std::cout << elem.value() << std::endl;
        } else {
            std::cout << "元素无效" << std::endl;
        }
    }
}

6.1 通用命令的使用

genetric.cpp 文件:

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <chrono>
#include <thread>
#include <sw/redis++/redis++.h>

#include "util.hpp"

using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;
using sw::redis::Redis;

// get 和 set 的使用
void test1(Redis& redis) {
    cout << "get 和 set 的使用" << endl;

    // 清空数据库,避免之前残留的数据有干扰
    redis.flushall();

    // 使用 set 设置 key
    redis.set("key1", "111");
    redis.set("key2", "222");
    redis.set("key3", "333");

    // 使用 get 获取到 key 对应的 value
    auto value1 = redis.get("key1");
    if(value1) {
        cout << "value1 = " << value1.value() << endl;
    } else {
        cout << "当前 key 不存在" << endl;
    }

    auto value2 = redis.get("key2");
    if(value2) {
        cout << "value2 = " << value2.value() << endl;
    } else {
        cout << "当前 key 不存在" << endl;
    }

    auto value3 = redis.get("key3");
    if(value3) {
        cout << "value3 = " << value3.value() << endl;
    } else {
        cout << "当前 key 不存在" << endl;
    }

    auto value4 = redis.get("key4");
    if(value4) {
        cout << "value4 = " << value4.value() << endl;
    } else {
        cout << "当前 key 不存在" << endl;
    }
}

// exists 的使用
void test2(Redis& redis) {
    cout << "exists" << endl;

    redis.flushall();

    redis.set("key", "111");
    redis.set("key3", "111");

    auto ret = redis.exists("key");
    cout << ret << endl;

    ret = redis.exists("key2");
    cout << ret << endl;

    ret = redis.exists({"key1", "key2", "key3"});
    cout << ret << endl;
}

// del 的使用
void test3(Redis& redis) {
    cout << "del" << endl;
    redis.flushall();

    redis.set("key1", "111");
    redis.set("key2", "222");

    vector<string> input{"key1", "key2", "key3"};
    auto ret = redis.del(input.begin(), input.end());
    cout << ret << endl;

    ret = redis.exists({"key1", "key2"});
    cout << ret << endl;
}

// keys 的使用
void test4(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");
    redis.set("key6", "666");

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

void test5(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(3s);

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

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("tcp://127.0.0.1:6379");
    
    // test1(redis);
    // test2(redis);
    // test3(redis);
    // test4(redis);
    // test5(redis);
    test6(redis);
}

get 和 set:test1()结果:

exists:test2()结果:

del:test3()结果:

keys:test4()结果:

expire and ttl:test5()结果:

type:test6()结果:

6.2 string的使用

string.cpp 文件:

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <chrono>
#include <thread>

#include <sw/redis++/redis++.h>
#include "util.hpp"

using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;

using sw::redis::Redis;

using namespace std::chrono_literals;

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;
    }
}

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;
}

void test3(Redis& redis) {
    std::cout << "set NX 和 XX" << std::endl;
    redis.flushall();

    redis.set("key", "111");

    // set 的重载版本中, 没有单独提供 NX 和 XX 的版本, 必须搭配过期时间的版本来使用. 
    redis.set("key", "222", 0s, sw::redis::UpdateType::EXIST);

    auto value = redis.get("key");
    if (value) {
        std::cout << "value: " << value.value() << std::endl;
    } else {
        std::cout << "key 不存在!" << std::endl;
    }
}

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") });

    // 第二种写法, 可以把多个键值对提前组织到容器中. 以迭代器的形式告诉 mset
    vector<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;
    }
}

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

void test6(Redis& redis) {
    std::cout << "getrange 和 setrange" << std::endl;
    redis.flushall();

    redis.set("key", "abcdefghijk");

    string result = redis.getrange("key", 2, 5);
    std::cout << "result: " << result << std::endl;

    redis.setrange("key", 2, "xyz");

    auto value = redis.get("key");
    std::cout << "value: " << value.value() << std::endl;
}

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("tcp://127.0.0.1:6379");

    // test1(redis);
    // test2(redis);
    // test3(redis);
    // test4(redis);
    // test5(redis);
    // test6(redis);
    test7(redis);
    
    return 0;
}

get 和 set:test1()结果:

set 带有超时时间:test2()结果:

set NX 和 XX:test3()结果:

mset 带有超时时间:test4()结果:

mget 带有超时时间:test5()结果:

getrange 和 setrange 带有超时时间:test6()结果:

incr 和 dec 带有超时时间:test7()结果:

6.3 list的使用

list.cpp 文件:

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <thread>
#include <chrono>
#include <sw/redis++/redis++.h>
#include "util.hpp"

using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;
using sw::redis::Redis;

using namespace std::chrono_literals;

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

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

void test3(Redis& redis) {
    std::cout << "lpop 和 rpop" << std::endl;
    redis.flushall();

    // 构造一个 list
    redis.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;
    }
}

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;
    }
}

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("tcp://127.0.0.1:6379");
    // test1(redis);
    // test2(redis);
    // test3(redis);
    // test4(redis);
    test5(redis);
    return 0;
}

lpush 和 lrange:test1()结果:

rpush:test2()结果:

lpop 和 rpo:test3()结果:

blpop:test4()结果:

llen:test5()结果:

6.4 set的使用

set.cpp 文件:

#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <unordered_map>
#include <sw/redis++/redis++.h>

#include "util.hpp"

using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;
using std::set;

using sw::redis::Redis;

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

void test2(Redis& redis) {
    std::cout << "sismember" << std::endl;
    redis.flushall();

    redis.sadd("key", {"111", "222", "333", "444"});

    bool result = redis.sismember("key", "555");
    std::cout << "result: " << result << std::endl;
}

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;
}

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;
    }
}

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

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("tcp://127.0.0.1:6379");
    // test1(redis);
    // test2(redis);
    // test3(redis);
    // test4(redis);
    // test5(redis);
    test6(redis);
    return 0;
}

sadd 和 smembers:test1()结果:

sismember:test2()结果:

scard:test3()结果:

spop:test4()结果:

sinter:test5()结果:

sinterstore:test6()结果:

6.5 hash的使用

hash.cpp 文件:

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <sw/redis++/redis++.h>

#include "util.hpp"

using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;

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;
    }
}

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", "f4");
    std::cout << "result: " << result << std::endl;
}

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;

    result = redis.hdel("key", {"f2", "f3"});
    std::cout << "result: " << result << std::endl;

    long long len = redis.hlen("key");
    std::cout << "len: " << len << 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);
}

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("tcp://127.0.0.1:6379");
    // test1(redis);
    // test2(redis);
    // test3(redis);
    // test4(redis);
    test5(redis);
    return 0;
}

hset 和 hget:test1()结果:

hexits:test2()结果:

hdel:test3()结果:

hkeys 和 hvals:test4()结果:

hmget 和 hmset:test5()结果:

6.6 zset的使用

zset.cpp 文件:

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <sw/redis++/redis++.h>

#include "util.hpp"

using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::unordered_map;

using sw::redis::Redis;

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 同时带有 score
    vector<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);
}

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;
}

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;
}

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;
    }
}

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("tcp://127.0.0.1:6379");
    // test1(redis);
    // test2(redis);
    // test3(redis);
    // test4(redis);
    test5(redis);
    return 0;
}

zadd 和 zrange:test1()结果:

zcard:test2()结果:

zrem:test3()结果:

zscore:test4()结果:

zrank:test5()结果:

redis学习打卡🥳


http://www.kler.cn/a/520537.html

相关文章:

  • 单片机基础模块学习——DS18B20温度传感器芯片
  • BAHD酰基转移酶对紫草素的手性催化-文献精读105
  • VB6.0 显示越南语字符
  • 基于RDMA GPUDirect技术的NCCL XCCL库体系结构效率问题疑补
  • 笔灵ai写作技术浅析(二):自然语言处理
  • 「 机器人 」扑翼飞行器混合控制策略缺点浅谈
  • 【深度学习】 UNet详解
  • 实用工具推荐----wsl安装
  • langchain基础(一)
  • 从 JIRA 数据到可视化洞察:使用 Python连接jira
  • 二次封装的方法
  • Django 多环境配置实战指南
  • Greenplum临时表未清除导致库龄过高处理
  • mysql数据库不允许远程链接时的解决办法
  • mapStruct 使用踩坑指南
  • C++ 自定义字面量
  • 小试牛刀调整Prompt,优化Token消耗
  • 电子应用设计方案104:智能家庭AI弹簧床系统设计
  • 「 机器人 」仿生扑翼飞行器中的“被动旋转机制”概述
  • Shotcut新版来袭,新增HSL滤镜、硬件编码,剪辑更流畅
  • 激光晶体材料行业深度分析
  • 大模型——增量预训练
  • ASP.NET Core WebAPI的异步及返回值
  • 自动化部署(二):Jenkins持续集成(CI/CD)
  • 自动化测试的学习路线
  • 4.flask-SQLAlchemy,表Model定义、增删查改操作