Redis:cpp.redis++通用接口

news2024/10/6 20:39:39

Redis:cpp.redis++通用接口

    • redis对象
    • 通用接口
      • set & get
      • exists
      • del
      • flushall
      • keys
      • ttl
      • expire
      • type


本博客讲解redisC++客户端redis-plus-plus,这个版本的客户端,接口和redis原生命令几乎完全一致,博客内部不会详细讲解每个接口的具体功能,因为和redis命令是一样的,而是重点讲解器用法与参数。

redis对象

redis的所有操作都基于一个redis对象。

C++文件中写入以下代码:

#include <iostream>
#include <sw/redis++/redis++.h>

int main()
{
    sw::redis::Redis redis("tcp://127.0.0.1:6379");
    std::string result = redis.ping();
    std::cout << result << std::endl;

    return 0;
}

在默认的路径下,redis++.h头文件放在了sw/redis++/目录下,其中sw是库作者的名称缩写。

main函数中,先创建一个Redis对象,其包含在命名空间sw::redis::内部。在创建对象时,要制定ip和端口号,格式如下:

tcp://IP地址:端口

其中redis的默认端口为6379

redis可以使用ping来检测连通性,通过redis.ping(),会返回一个字符串。

随后对代码进行编译:

g++ -o test_redis test.cpp -std=c++17 -l hiredis -l redis++ -l pthread

redis++需要依赖三个库:hiredisredis++pthread

如果运行程序,输出了PONG,那么说明redis是正常可用的。


通用接口

set & get

  • set函数声明如下:
bool set(const StringView &key,
            const StringView &val,
            const std::chrono::milliseconds &ttl = std::chrono::milliseconds(0),
            UpdateType type = UpdateType::ALWAYS);

此处有一个StringView类型,是一个只读的字符串,其效率比std::string更高,不过在C++17中也支持了std::string_view。只需要把它当作一般的std::string也没什么大问题。

函数中,前两位是keyvalue其余的都是缺省参数,所以可以只输入keyvalue

  • get函数声明如下:
OptionalString get(const StringView &key);

get的返回值也很特别,是一个OptionalString类型,这是因为redis中如果查询为空,会返回nil,对于std::string不好表示这样的空,所以使用了OptionalString来处理,一般用auto接收即可。

要注意的是OptionalString不支持operator<<,要通过.value()函数,获取其内部包含的std::string即可。

示例:

#include <iostream>
#include <sw/redis++/redis++.h>

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

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

    auto ret1 = redis.get("key1");
    std::cout << ret1.value() << std::endl;

    auto ret2 = redis.get("key2");
    std::cout << ret2.value() << std::endl;
    
    auto ret3 = redis.get("key3");
    std::cout << ret3.value() << std::endl;

    return 0;
}

输出结果:

111
222
terminate called after throwing an instance of 'std::bad_optional_access'
  what():  bad optional access
Aborted (core dumped)

此处由于没有插入key3,所以get时得到的值为nil,最后输出时抛出了异常。

如果要处理这个情况,那要用到OptionalString的另一个特性。OptionalString可以隐式转化为bool类型,如果元素有效则为true,元素无效则为false

输出之前,只需要判断一下返回值是否为true即可:

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

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

    auto ret1 = redis.get("key1");
    if (ret1)
        std::cout << ret1.value() << std::endl;

    auto ret2 = redis.get("key2");
    if (ret2)
        std::cout << ret2.value() << std::endl;

    auto ret3 = redis.get("key3");
    if (ret3)
        std::cout << ret3.value() << std::endl;

    return 0;
}

exists

  • exists用于检测key是否存在,函数声明如下:
long long exists(const StringView &key);

这个很简单,就是判断一个key是否存在。

但是其为什么要以long long作为返回值?其实exists还有另一个函数重载:

template <typename T>
long long exists(std::initializer_list<T> il);

其接收一个初始化列表,也就是可以同时接收多个key,此时有多少个key存在,就返回多少。

示例:

#include <iostream>
#include <sw/redis++/redis++.h>

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

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

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

    return 0;
}

输出结果:

1
2

此处要注意,输入的是一个初始化列表(C++11),需要用{}把所有参数先包起来,构成一个初始化列表。


del

  • del用于删除key,函数声明如下:
long long del(const StringView &key);

template <typename T>
long long del(std::initializer_list<T> il);

exists一样,支持删除一个或多个key,删除多个时要通过初始化列表。


flushall

  • flushall用于清空整个redis,函数声明如下:
void flushall(bool async = false);

该接口会清空redis内的所有数据,开发环境慎用,一般而言参数直接用默认的false即可。


keys

  • keys用于搜索符合条件的keykeys函数声明如下:
template <typename Output>
void keys(const StringView &pattern, Output output);

keys用于搜索所有符合条件的key,此处第一个参数pattern是匹配模式,output是一个插入迭代器,用于获取符合条件的key,元素类型是字符串,std::string或者StringView

int main()
{
    sw::redis::Redis redis("tcp://127.0.0.1:6379");
    redis.flushall();

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

    std::vector<std::string> result;
    auto it = std::back_inserter(result);

    redis.keys("*", it);

    for (auto& ret : result)
        std::cout << ret << std::endl;

    return 0;
}

输出结果:

key3
key2
key1
key4

此处的插入迭代器,是一种专门用于将元素插入到容器中的迭代器,主要有以下三种:

  1. std::front_insert_iterator:在容器头部插入
  2. std::back_insert_iterator:在容器尾部插入
  3. std::insert_iteraotr:在容器任意位置插入

这种迭代器,++--都是无效的,核心是operator=

比如模拟实现一个vector的插入迭代器:

template <typename T>
class InsertIterator {
public:
    // 构造函数,保存容器的引用和插入位置的迭代器
    InsertIterator(std::vector<T>& vec, typename std::vector<T>::iterator pos)
        : vec_(vec), pos_(pos) {}

    // 重载赋值操作符,实现插入逻辑
    InsertIterator& operator=(const T& value) {
        pos_ = vec_.insert(pos_, value);
        return *this;
    }

    // 重载前置和后置增加操作符,因为插入操作不改变迭代器位置
    InsertIterator& operator++() { return *this; }
    InsertIterator& operator++(int) { return *this; }

    // 重载解引用操作符,以便可以链式调用
    InsertIterator& operator*() { return *this; }

private:
    std::vector<T>& vec_;
    typename std::vector<T>::iterator pos_;
};

operator=内部,调用vector.insert接口,完成元素插入容器的操作,此时pos也会自动指向新的位置。

这种迭代器,可以完成插入与容器的解耦合,redis返回的结果集,可以不用重载各种setvector等容器,而是使用统一的插入迭代器完成。


ttl

  • ttl用于获取key的剩余超时时间,函数声明如下:
long long ttl(const StringView &key);

这个函数结合下一个接口一起展示。


expire

  • expire用于设置超时时间,函数声明如下:
bool expire(const StringView &key, long long timeout);
bool expire(const StringView &key, const std::chrono::seconds &timeout);

expire设置超时时间时,有两种模式,第一个重载的timeoutlong long类型,以秒为单位,也可以使用std::chrono::seconds来控制。

返回值与redis原生的ttl完全一致,如果key不存在返回-2,如果key存在但是没有超时时间返回-1

示例:

#include <iostream>
#include <chrono>

#include <sw/redis++/redis++.h>

int main()
{
    sw::redis::Redis redis("tcp://127.0.0.1:6379");
    redis.flushall();

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

    redis.expire("key1", 10);
    redis.expire("key2", std::chrono::seconds(1));

    std::cout << redis.ttl("key1") << std::endl;
    std::cout << redis.ttl("key2") << std::endl;
    std::cout << redis.ttl("key3") << std::endl;
    std::cout << redis.ttl("key4") << std::endl;

    return 0;
}

输出结果:

10
1
-1
-2

type

  • type用于获取key对于的value的类型,函数声明如下:
std::string type(const StringView &key);

其返回值是标准的std::string


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2192861.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何使用ssm实现基于Java的校园二手物品交易平台的设计与实现+vue

TOC ssm789基于Java的校园二手物品交易平台的设计与实现vue 绪论 1.1 研究背景 在这个推荐个性化的时代&#xff0c;采用新技术开发一个校园二手物品交易平台来分享和展示内容是一个永恒不变的需求。本次设计的校园二手物品交易平台有管理员&#xff0c;商家&#xff0c;用…

Leetcode - 周赛417

目录 一&#xff0c;3304. 找出第 K 个字符 I 二&#xff0c;3305. 元音辅音字符串计数 I 三&#xff0c;3307. 找出第 K 个字符 II 一&#xff0c;3304. 找出第 K 个字符 I 本题数据范围小&#xff0c;可以直接模拟&#xff0c;代码如下&#xff1a; class Solution {publ…

鸿蒙harmonyos next flutter混合开发之开发FFI plugin

创建FFI plugin summation&#xff0c;默认创建的FFI plugin是求两个数的和 flutter create --templateplugin_ffi summation --platformsandroid,ios,ohos 创建my_application flutter create --org com.example my_application 在my_application项目中文件pubspec.yaml引…

缓存数据减轻服务器压力

问题:不是所有的数据都需要请求后端的 不是所有的数据都需要请求后端的,有些数据是重复的、可以复用的解决方案:缓存 实现思路:每一个分类为一个key,一个可以下面可以有很多菜品 前端是按照分类查询的,所以我们需要通过分类来缓存缓存代码 /*** 根据分类id查询菜品** @pa…

《计算机原理与系统结构》学习系列——计算机的算数运算(下)

系列文章目录 目录 浮点数的表示和运算浮点数的表示浮点数的规格化浮点数标准IEEE754浮点数表示范围浮点数的转换浮点数的运算浮点数加法浮点数加法的硬件实现 精度浮点乘法浮点运算硬件 MIPS中的浮点指令 浮点数的表示和运算 浮点数的表示 表达非整型的数 可以表达很小和很大…

重磅来袭!CMSIS-DAP 脱机烧录器 EasyFlasher 发布~

重磅来袭&#xff01;CMSIS-DAP 脱机烧录器 EasyFlasher 发布~ 目录 重磅来袭&#xff01;CMSIS-DAP 脱机烧录器 EasyFlasher 发布~相关文章1、前言1、产品特点2、功能说明3、支持芯片4、关于烧录5、写在最后 某宝店铺&#xff1a;觉皇工作室 购买链接&#xff1a;https://item…

【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象

文章目录 请求1. 传递单个参数注意事项1 . **正常传递参数**2 . **不传递 age 参数**3 . **传递参数类型不匹配** 2. 传递多个参数3. 传递对象 请求 访问不同的路径&#xff0c;就是发送不同的请求。在发送请求时&#xff0c;可能会带一些参数&#xff0c;所以学习 Spring 的请…

习题5 循环

选择题 1、如下程序的运行结果为 【 正确答案: B】。 A.9 B.8 C.7 D.6 2、C语言的for语句中的表达式可以部分或全部省略&#xff0c;但两个 【 正确答案: C】不能省略。 但当三个表达式均省略后&#xff0c;因缺少判断条件&#xff0…

构建llama.cpp并在linux上使用gpu

使用gpu构建llama.cpp 更多详情参见https://github.com/abetlen/llama-cpp-python&#xff0c;官网网站会随着版本迭代更新。 下载并进入llama.cpp 地址&#xff1a;https://github.com/ggerganov/llama.cpp 可以下载到本地再传到服务器上 git clone https://github.com/gg…

AI特征工程-如何缓解模型过拟合

一、什么是模型过拟合&#xff1f; 1、举个例子 如上图第三个模型解释为出现了过拟合现象&#xff0c;过度的拟合了训练数据&#xff0c;而没有考虑到泛化能力&#xff0c;从而在新数据上表现不佳。 二、如何确定模型过拟合了 我们通常没有办法直观的看到过拟合。通常有以下几…

【数据分享】2000—2023年我国省市县三级逐年植被覆盖度(FVC)数据(Shp/Excel格式)

之前我们分享过2000—2023年逐月植被覆盖度&#xff08;FVC&#xff09;栅格数据&#xff08;可查看之前的文章获悉详情&#xff09;和Excel和Shp格式的省市县三级逐月FVC数据&#xff08;可查看之前的文章获悉详情&#xff09;&#xff0c;原始的逐月栅格数据来源于高吉喜学者…

【Python】Python知识总结浅析

Python是一种高级编程语言&#xff0c;由Guido van Rossum于1991年首次发布。它以简洁的语法和强大的功能著称&#xff0c;适用于多种应用场景&#xff0c;包括Web开发、数据分析、人工智能、自动化脚本等。 易于学习和使用&#xff1a;Python的语法简洁明了&#xff0c;适合初…

信息安全工程师(36)访问控制主要产品与技术指标

前言 访问控制是确保系统资源安全的重要手段&#xff0c;其主要产品和技术指标对于理解和实施有效的访问控制策略至关重要。 一、访问控制主要产品 访问控制产品种类繁多&#xff0c;根据应用场景和需求的不同&#xff0c;可以分为以下几类&#xff1a; 防火墙&#xff1a; 功能…

【C语言】VS调试技巧

文章目录 什么是bug什么是调试&#xff08;debug&#xff09;debug和releaseVS调试快捷键监视和内存观察编程常⻅错误归类 什么是bug bug本意是昆⾍”或“⾍⼦”&#xff0c;现在⼀般是指在电脑系统或程序中&#xff0c;隐藏着的⼀些未被发现的缺陷或问题&#xff0c;简称程序…

Pytorch基础:网络层

文章目录 1.卷积层-Convolution Layers1.1 1d/2d/3d卷积1.2卷积--nn.Conv2d1.3转置卷积(实现上采样) 2.池化层3.线性层—Linear Layer4.激活函数层—Activate Layer 1.卷积层-Convolution Layers 卷积运算:卷积运算在输入信号(图像)上滑动,相应位置上进行乘加. 卷积核:又称过滤…

java版鸿鹄电子招投标系统功能架构设计 核心功能设计 鸿鹄电子招投标采购系统源码

java版鸿鹄电子招投标系统功能架构设计 核心功能设计 鸿鹄电子招投标采购系统源码

Linux高级编程_30_管道

文章目录 管道作用&#xff1a;分类&#xff1a; 前置知识&#xff1a;复制文件描述符dupdup2 【推荐使用】 无名管道概述&#xff1a; pipe函数实现&#xff1a; ps -A | grep bash 有名管道&#xff1a;实现有名管道的聊天无名管道与有名管道的区别? 管道 作用&#xff1a;…

小红书算法岗面试,竞争太激烈了

最近已有不少大厂都在秋招宣讲了&#xff0c;也有一些在 Offer 发放阶段。 节前&#xff0c;我们邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。 针对新手如何入门算法岗、该如何准备面试攻略、面试常考点、大模型技术趋势、算法项目落地经验分享等热门话题进行了…

排版套料系统设计说明

先上效果图 项目地址 1.产品介绍 产品名称&#xff1a;StreamFit 智能排版套料系统 主要功能&#xff1a; 智能排版优化 功能描述&#xff1a;StreamFit 利用先进的算法技术&#xff0c;自动对各类材料&#xff08;如布料、金属板材、纸张等&#xff09;进行高效排版布局&am…

一次Mysql数据库活跃连接数高告警的排查方法

基础相关知识 在现代应用中&#xff0c;数据库的性能和稳定性直接影响到整个系统的运行情况。活跃连接数高的告警往往意味着数据库负载过重&#xff0c;可能会导致性能下降甚至服务不可用。 活跃连接数指的是当前与数据库建立连接并且处于活动状态的连接数量。 高活跃连接数…