Redis:cpp.redis++类型操作

news/2024/10/9 15:48:35/

Redis:cpp.redis++类型操作

    • string
      • set
      • mset
      • mget
      • getrange
      • setrange
      • incrby
      • decrby
    • list
      • lpush
      • rpush
      • lrange
      • llen
      • lpop
      • rpop
      • blpop
      • brpop
    • set
      • sadd
      • smemebers
      • sismember
      • scard
      • spop
      • sinter
      • sinterstore
    • hash
      • hset
      • hget
      • hexists
      • hdel
      • hkeys
      • hvals
      • hmset
      • hmget
    • zset
      • zadd
      • zrange
      • zcard
      • zrem
      • zscore
      • zrank
    • 总结


本博客讲解rediisC++客户端redis++,五大基本类型操作。大部分接口和redis原生命令没有区别,只是有小部分C++语法问题。所有接口可以参考文档:[redis-plus-plus/redis.h],本博客只讲解各个类型最核心的接口,以及部分语法注意事项。

本博客讲解接口比较枯燥,接口是看不完的,可以选择直接看总结,那里归纳了redis++的接口设计规则。

string

set

stringgetset已经在通用接口中讲解过了,但是还有两个默认参数没有说明。

bool set(const StringView &key,const StringView &val,const std::chrono::milliseconds &ttl = std::chrono::milliseconds(0),UpdateType type = UpdateType::ALWAYS);

set的第三个参数用于设置超时时间,第四个参数用于设置NX | XX选项,有以下三种选项:

  • ALWAYS:总是插入新数据,默认值
  • NOT_SXISTkey不存在时才插入,存在则什么也不干
  • EXISTkey存在时才更新,不存在则什么也不干

示例:

#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("str1", "111", std::chrono::seconds(5));std::cout << redis.ttl("str1") << std::endl;redis.set("str2", "222", std::chrono::seconds(0), sw::redis::UpdateType::NOT_EXIST);std::cout << redis.get("str2").value() << std::endl;redis.set("str2", "333", std::chrono::seconds(0), sw::redis::UpdateType::NOT_EXIST);std::cout << redis.get("str2").value() << std::endl;return 0;
}

输出结果:

5
222
222

第一次set测试超时时间,使用ttl检测超时时间为5s。第二次用set测试NOT_EXIST,由于str2不存在,插入成功222。第三次更新str2333,但是设置模式为NOT_EXIST,由于str2已经存在,设置失败,str2依然是222

此处想要使用UpdateType,必须先设置超时时间,如果不想要超时间,就设为0s


mset

  • mset用于同时设置多个key,函数原型如下:
template <typename Input>
void mset(Input first, Input last);template <typename T>
void mset(std::initializer_list<T> il);

第一个重载,要输入一个容器迭代器,容器存储的类型是std::pair<std::string, std::string>,有以下两种用法:

std::vector<std::pair<std::string, std::string>> kvs1 = {{"k1", "v1"}, {"k2", "v2"}};
redis.mset(kvs1.begin(), kvs1.end());
std::unordered_map<std::string, std::string> kvs2 = {{"k3", "v3"}, {"k4", "v4"}};
redis.mset(kvs2.begin(), kvs2.end());

第一种使用std::vector直接存储std::pair,此时传入std::vector的首尾迭代器进行构造。

第二种则是使用C++库中自带的键值对形式的容器,比如std::mapstd::unordered_map,传入首尾迭代器进行构造。

而第二个重载,要传入一个初始化列表,列表的每个元素也是std::pair<std::string, std::string>

redis.mset({std::make_pair("k1", "v1"), std::make_pair("k2", "v2"), std::make_pair("k3", "v3")});

mget

  • mset用于同时获取多个key,函数原型如下:
template <typename Input, typename Output>
void mget(Input first, Input last, Output output);template <typename T, typename Output>
void mget(std::initializer_list<T> il, Output output) {mget(il.begin(), il.end(), output);
}

mget也有两种函数重载,第一种把要查询的key放到input容器中,然后输入容器的头尾迭代器。还需要一个output迭代器,用于接收输出的value

std::vector<std::string> keys = {"k1", "k2", "k3"};
std::vector<OptionalString> vals;
redis.mget(keys.begin(), keys.end(), std::back_inserter(vals));

同样的,mget也可以使用初始化列表:


std::vector<OptionalString> vals;
redis.mget({"k1", "k2", "k3"}, std::back_inserter(vals));

getrange

  • getrange获取指定范围内的字符,函数声明如下:
std::string getrange(const StringView &key, long long start, long long end);

第一个参数指定要查询的key,后两个参数分别是起始下标和终止下标,返回一个std::string,如果为空就返回空字符串,


setrange

  • setrange用于从指定下标开始覆盖字符,函数声明如下:
long long setrange(const StringView &key, long long offset, const StringView &val);

第一个参数指定key,第二个参数为起始下标,从起始下标开始往后的字符串,被val覆盖。


incrby

  • incrby用于给value增加指定值,函数声明如下:
long long incrby(const StringView &key, long long increment);

第一个参数指定key,第二个参数为增量,可以为负数。


decrby

long long decrby(const StringView &key, long long decrement);

第一个参数指定key,第二个参数为减量,可以为负数。

此处有一个要注意的小问题就是,在redisint是使用string来存储的,但是get得到的是OptionalString,此时要自己进行字符串到数字的转化。


list

lpush

  • lpush用于插入元素到列表头部,函数声明如下:
long long lpush(const StringView &key, const StringView &val);template <typename Input>
long long lpush(const StringView &key, Input first, Input last);template <typename T>
long long lpush(const StringView &key, std::initializer_list<T> il) {return lpush(key, il.begin(), il.end());
}

第一个函数重载,用于只插入一个元素的情况,第二个重载需要传入一个容器的迭代器,元素类型为std::string。第三个重载为初始化列表。

容器迭代器版本:

std::vector<std::string> elements = {"e1", "e2", "e3"};
redis.lpush("list", elements.begin(), elements.end());

初始化列表版本:

redis.lpush("list", {"e1", "e2", "e3"});

rpush

  • rpush用于插入元素到列表尾部,函数声明如下:
long long rpush(const StringView &key, const StringView &val);template <typename Input>
long long rpush(const StringView &key, Input first, Input last);template <typename T>
long long rpush(const StringView &key, std::initializer_list<T> il) {return rpush(key, il.begin(), il.end());
}

这个用法和lpush完全一致,只是该函数用于尾插。


lrange

  • lrange用于获取list指定范围内的元素,函数声明如下:
template <typename Output>
void lrange(const StringView &key, long long start, long long stop, Output output);

指定[start, stop]闭区间,最后将结果通过输出迭代器output输出到容器中。

示例:

redis.lrange("list", 0, -1, std::back_inserter(elements));

llen

  • llen用于获取list的长度,函数声明如下:
long long llen(const StringView &key);

lpop

  • lpop用于获取并删除列表的头部元素,函数声明如下:
OptionalString lpop(const StringView &key);

此处注意返回值是OptionalString ,有可能为空,要进行检查。

示例:

auto element = redis.lpop("list");
if (element)std::cout << *element << std::endl;
elsestd::cout << "list is empty or list does not exist" << std::endl;

rpop

  • rpop用于获取并删除列表的尾部元素,函数声明如下:
OptionalString rpop(const StringView &key);

lpop用法一致。


blpop

  • blpop用于阻塞等待,获取头部元素,函数声明如下:
// 单key版本
OptionalStringPair blpop(const StringView &key, long long timeout);OptionalStringPair blpop(const StringView &key,const std::chrono::seconds &timeout = std::chrono::seconds{0});// 多key,容器迭代器版本
template <typename Input>
OptionalStringPair blpop(Input first, Input last, long long timeout);template <typename Input>
OptionalStringPair blpop(Input first,Input last,const std::chrono::seconds &timeout = std::chrono::seconds{0});// 多key,初始化列表版本
template <typename T>
OptionalStringPair blpop(std::initializer_list<T> il, long long timeout);template <typename T>
OptionalStringPair blpop(std::initializer_list<T> il,const std::chrono::seconds &timeout = std::chrono::seconds{0});

blpop有六个重载,但是其实这只是同样的功能的不同传参形式而已。对于redis的阻塞等待,其可以传入一个或者多个key。前两个函数重载就是对单个key的特化,它们的key都是一个StringViewtimeout用于设置超时时间,而超时时间又可以分为long long类型和std::chrono类型,所以有两个重载。

对于多个key的情况,为了传入多个key,第三个和第四个重载使用了容器迭代器的传参方式,容器元素为key。而第五个和第六个重载,使用了初始化列表的传参方式。

blpop的返回值,是一个OptionalStringPair,第一个成员是key,表示该数据是从哪一个list得到的,第二个成员OptionalStringPair.value().second才是获取到的值。

另外的,OptionalStringPair有两种方式可访问成员,第一种是通过value()方法获取std::pair

OptionalStringPair.value().first;
OptionalStringPair.value().second;

另一种是通过->直接访问:

OptionalStringPair->first;
OptionalStringPair->second;

由于该函数也有可能返回空,所以也是Optional系列,使用之前要检测是否为空。

示例:

std::vector<std::string> keys = {"k1", "k2", "k3"};
auto ret = redis.blpop(keys.begin(), keys.end(), 10);
if (ret)std::cout << ret->first << " : " << ret->second << std::endl;

brpop

  • brpop用于阻塞等待,获取尾部元素,函数声明如下:
// 单key版本
OptionalStringPair brpop(const StringView &key, long long timeout);OptionalStringPair brpop(const StringView &key,const std::chrono::seconds &timeout = std::chrono::seconds{0});// 多key,容器迭代器版本
template <typename Input>
OptionalStringPair brpop(Input first, Input last, long long timeout);template <typename Input>
OptionalStringPair brpop(Input first,Input last,const std::chrono::seconds &timeout = std::chrono::seconds{0});// 多key,初始化列表版本
template <typename T>
OptionalStringPair brpop(std::initializer_list<T> il, long long timeout);template <typename T>
OptionalStringPair brpop(std::initializer_list<T> il,const std::chrono::seconds &timeout = std::chrono::seconds{0});

这个用法和blpop完全一致。


set

sadd

  • sadd用于往set中插入元素,或者创建一个set,函数声明如下:
long long sadd(const StringView &key, const StringView &member);template <typename Input>
long long sadd(const StringView &key, Input first, Input last);template <typename T>
long long sadd(const StringView &key, std::initializer_list<T> il);

三种初始化方法,分别是一次只添加一个元素、使用容器迭代器、使用初始化列表。

示例:

redis.sadd("set1", "value1");std::set<std::string> values;
redis.sadd("set2", values.begin(), values.end());
redis.sadd("set3", {"value1", "value2"});

smemebers

  • smembers用于获取set中的所有元素,函数声明如下:
template <typename Output>
void smembers(const StringView &key, Output output);

示例:

std::unordered_set<std::string> members1;
redis.smembers("set", std::inserter(members1, members1.begin()));
std::vector<std::string> members2;
redis.smembers("set", std::back_inserter(members2));

此处要注意,std::set或者std::unordered_set的插入迭代器,必须使用inserter,因为其没有提供头尾插入的接口。


sismember

  • sismember用于检测一个数据是否在set中,函数声明如下:
bool sismember(const StringView &key, const StringView &member);

scard

  • scard用于获取元素的个数,函数声明如下:
long long scard(const StringView &key);

spop

  • spop用于获取set中的一个随机元素,函数声明如下:
OptionalString spop(const StringView &key);template <typename Output>
void spop(const StringView &key, long long count, Output output);

示例:

std::vector<std::string> members;
redis.spop("set", 10, std::back_inserter(members));

sinter

  • sinter用于求集合的交集,函数声明如下:
template <typename Input, typename Output>
void sinter(Input first, Input last, Output output);template <typename T, typename Output>
void sinter(std::initializer_list<T> il, Output output);

第一个重载输入容器迭代器,第二个重载输入初始化列表,这里面放的是要进行求交集的多个set

最后将结果输出到插入迭代器output中。

示例:

std::set<std::string> results;
auto it = std::inserter(result, resulter.end());
redis.sinter({"set1", "set2"}, it);

sinterstore

  • sinterstore用于求出集合的交集,并放到其他集合中,函数声明如下:
long long sinterstore(const StringView &destination, const StringView &key);template <typename Input>
long long sinterstore(const StringView &destination,Input first,Input last);template <typename T>
long long sinterstore(const StringView &destination,std::initializer_list<T> il);

三个重载的第一个参数都是destination,求出的交集会被存放到这个set中。第一个重载是对单个set的特化,后续两个重载分别输入一个迭代器或者初始化列表,内部放要求交集的多个set


hash

hset

  • hset用于向哈希表插入元素,或者创建一个哈希,函数声明如下:
long long hset(const StringView &key, const StringView &field, const StringView &val);long long hset(const StringView &key, const std::pair<StringView, StringView> &item);template <typename Input>
auto hset(const StringView &key, Input first, Input last)-> typename std::enable_if<!std::is_convertible<Input, StringView>::value, long long>::type;template <typename T>
long long hset(const StringView &key, std::initializer_list<T> il);

hset有 四个重载,前两个重载用于插入单个键值对,后两个重载用于插入多个键值对。


hget

  • hget用于获取hash中指定的field的值,函数声明如下:
OptionalString hget(const StringView &key, const StringView &field);

hexists

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

hdel

  • hdel用于删除指定的field,函数声明如下:
long long hdel(const StringView &key, const StringView &field);template <typename Input>
long long hdel(const StringView &key, Input first, Input last);template <typename T>
long long hdel(const StringView &key, std::initializer_list<T> il);

该接口支持同时删除多个field

示例:

redis.hdel("hash1", "field1");
redis,hdel("hash1", {"field2", "field3"});

hkeys

  • hkeys用于获取hash中所有的field,函数声明如下:
template <typename Output>
void hkeys(const StringView &key, Output output);

hkeys要使用插入迭代器获取返回值。

示例:

std::vector<std::string> fields;
auto it = std::back_inserter(fields);
redis.hekys("hash1", it);

hvals

  • hvals用于获取hash中所有的value,函数声明如下:
template <typename Output>
void hvals(const StringView &key, Output output);

用法同hvals


hmset

  • hmset用于设置多对field - value,函数声明如下:
template <typename Input>
void hmset(const StringView &key, Input first, Input last);template <typename T>
void hmset(const StringView &key, std::initializer_list<T> il);

分别是使用容器迭代器和初始化列表,其中容器的成员为std::pair

示例:

// 容器迭代器版本
std::unordered_map<std::string, std::string> m = {{"f1", "v1"}, {"f2", "v2"}};
redis.hmset("hash", m.begin(), m.end());
// 初始化列表版本
redis.hmset("hash", {std::make_pair("f1", "v1"), std::make_pair("f2", "v2")});

hmget

  • hmget用于同时获取多个field - value键值对,函数声明如下:
template <typename Input, typename Output>
void hmget(const StringView &key, Input first, Input last, Output output);template <typename T, typename Output>
void hmget(const StringView &key, std::initializer_list<T> il, Output output);

其中初始化列表,和容器迭代器用于输入多个fields,返回对应的value,通过插入迭代器输出到接收容器。

示例:

std::vector<OptionalString> vals;
redis.hmget("hash", {"f1", "f2"}, std::back_inserter(vals));

zset

zadd

  • zadd用于往zset中插入元素,函数声明如下:
long long zadd(const StringView &key,const StringView &member,double score,UpdateType type = UpdateType::ALWAYS,bool changed = false);template <typename Input>
long long zadd(const StringView &key,Input first,Input last,UpdateType type = UpdateType::ALWAYS,bool changed = false);template <typename T>
long long zadd(const StringView &key,std::initializer_list<T> il,UpdateType type = UpdateType::ALWAYS,bool changed = false);

第一个重载是插入单个元素的特化,后两个重载支持同时插入多个元素。插入多个元素时,可以通过容器迭代器或初始化列表。最后函数返回插入的元素个数。

最后两个参数在先前已经讲解过。

示例:

reids,zadd("zset1", {std::make_pair("lisa", 60.5), std::make_pair("bob", 20.5)});

zrange

  • zrange用于查询zset中指定范围的元素,函数声明如下:

template <typename Output>
void zrange(const StringView &key, long long start, long long stop, Output output);

这种范围查询,都有withscore选项,用于获取score,但是这个zrange只有一个重载,如何设置withoutscore

此处在zrange内部,会判断插入迭代器output指向的容器元素类型,如果容器元素是std::string,那么只返回field,如果是std::pair<std::string, double>,那么就会带着score一起返回。

示例:

// send *ZRANGE* command without the *WITHSCORES* option:
std::vector<std::string> result;
redis.zrange("zset", 0, -1, std::back_inserter(result));
// send command with *WITHSCORES* option:
std::vector<std::pair<std::string, double>> with_score;
redis.zrange("zset", 0, -1, std::back_inserter(with_score));

zcard

  • zcard用于获取zset中的元素个数,函数声明如下:
long long zcard(const StringView &key);

zrem

  • zrem用于删除zset的元素,函数声明如下:
long long zrem(const StringView &key, const StringView &member);template <typename Input>
long long zrem(const StringView &key, Input first, Input last);template <typename T>
long long zrem(const StringView &key, std::initializer_list<T> il)

同理,对于删除单个元素情况,直接传入member,当要删除多个时,将member放到容器中或者初始化列表。


zscore

  • zscore用于获取memberscore,函数声明如下:
OptionalDouble zscore(const StringView &key, const StringView &member);

zrank

  • zrank用于获取member的排名,函数声明如下:
OptionalLongLong zrank(const StringView &key, const StringView &member);

总结

其实你会发现,redis++的接口用法和redis原生的几乎没有区别。

在需要输入多个参数时,有两种方法:

  1. 使用容器保存参数,输入容器的迭代器
  2. 使用初始化列表直接传参

如果要传入键值对,那么就使用std::pair来维护键值关系。

另外的,常用的C++类型如下:

  • OptionalString:接收value返回值,可以判断是否为nil
  • StringViewkeyfield传参时使用的类型,只读字符串,不能对字符串进行增删操作,其实直接传std::string就行
  • long long:只要返回值是整数,几乎都用long long接收
  • doublezsetscore使用的类型

如果函数要输出多个变量,此时就要传入插入迭代器,这个在[Redis:cpp.redis++通用接口]讲解过。



http://www.ppmy.cn/news/1536716.html

相关文章

QT 通过鼠标事件实现图片的拖动和缩放

通过鼠标拖动来移动图片&#xff0c;并使用鼠标滚轮来缩放图片。 1、实现步骤&#xff1a; 1、移动图片&#xff1a; 使用QPoint记录图片的偏移量&#xff0c;当鼠标拖动时更新这个偏移量&#xff0c;在paintEvent()中根据偏移量绘制图片。2、缩放图片&#xff1a; 使用滚轮…

【网络安全】学过编程就是黑客?

前言 黑客&#xff0c;相信经常接触电脑的朋友们对这个词都不陌生&#xff0c;各类影视视频中黑客总是身处暗处&#xff0c;运筹帷幄&#xff0c;正是这种神秘感让我走向学习编程的道路&#xff0c;也正是如此让我明白黑客远没有我想象中那么“帅气”。 黑客 &#x1f4bb; 黑…

本地访问autodl的jupyter notebook

建立环境并安装jupyter conda create --name medkg python3.10 source activate medkg pip install jupyter 安装完成后&#xff0c;输入jupyter notebook --generate-config 输入ipython,进入python In [2]: from jupyter_server.auth import passwd In [3]: passwd(algori…

常见的负载均衡

1.常见的负载均衡服务 负载均衡服务是分布式系统中用于分配网络流量和请求的关键组件&#xff0c;它可以帮助提高应用程序的可用性、可扩展性和响应速度。以下是一些常用的负载均衡服务&#xff1a; Nginx&#xff1a;一个高性能的Web服务器和反向代理&#xff0c;广泛用于实现…

外国钞票面值检测系统源码分享[一条龙教学YOLOV8标注好的数据集一键训练_70+全套改进创新点发刊_Web前端展示]

外国钞票面值检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

钰泰ETA6096移动电源IC

描述 ETA6986 是一款开关锂离子电池充电器&#xff0c;能够为电池提供高达 5A 的充电电流&#xff0c;并在升压 OTG 操作中提供高达 3A 的电流。它采用电荷泵来实现非常快速的输入 OVP&#xff0c;对于充电&#xff0c;它使用专有的控制方案&#xff0c;无需电流感应电阻器即可…

CSID-GAN:基于生成对抗网络的定制风格室内平面设计框架论文阅读

CSID-GAN: A Customized Style Interior Floor Plan Design Framework Based on Generative Adversarial Network 摘要前言II. CSID-GAN METHODA. Overall FrameworkB. Algorithm and Loss Function III. DATASETS AND EVALUATION METRICSA. DatasetsB. Evaluation Metrics IV.…

【秋招笔试】10.08华为荣耀秋招(已改编)-(第二套)题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 本次的三题全部上线…