Redis-CPP通用接口
Redis对象
Redis客户端的所有操作都是基于Redis
对象来操作的。下面通过一段代码来看看使用Redis
客户端时需要哪些准备工作。通过这段代码可以知道客户端是否连接成功。
#include<iostream>
#include<string>
#include <sw/redis++/redis++.h>using namespace std;int main()
{// 创建Redis对象的时候,需要在构造函数中,指定redis服务器端地址和端口sw::redis::Redis redis("tcp://127.0.0.1:6379");// 调用ping方法,让客户端给服务器发了一个ping,然后服务器就会返回一个pong。string result = redis.ping();std::cout << result << endl;return 0;
}
需要使用Redis客户端时,需要包含相应的头文件<sw/redis++/redis++.h>
,其中sw
是作者的名称缩写。
在main
函数当中,需要先创建一个Redis
对象,它是在命名空间sw::redis::
里面,接着需要指定IP地址和端口号。其中6379
是redis
服务器的默认端口,由于我的redis
客户端和服务端是在同一台主机上,所以指定的是127.0.0.1
,如果是不同主机,则需要写对应主机的IP。
最后,通过ping
操作来检测连通性,如果连通成功,则会返回一个字符串PONG
。运行这段代码时,还需要3个库文件hiredis
、redis++
、pthread
。
g++ -o $@ $^ -std=c++17 /usr/local/lib/libredis++.a /usr/lib/x86_64-linux-gnu/libhiredis.a -l pthread
通用命令
重点讲解每个命令的用法和参数,具体用法可以学习这篇文章Redis命令使用。所有的接口可以看redis-plus-plus
的源码redis源码
get和set
- set函数原型如下:
bool set(const sw::redis::StringView &key, const sw::redis::StringView &val, const std::chrono::milliseconds &ttl = std::chrono::milliseconds(0), sw::redis::UpdateType type = sw::redis::UpdateType::ALWAYS)
这里的参数和之前set
命令的选项有很大的关联关系。key
的类型是StringView
,表明这是只读 的,不能修改。而对于std::string
类型是可修改的,既能写,也能读。StringView
的效率比string
的效率高。除了key
和value
,其余参数都是缺省值,可以不填。
- get函数原型如下:
OptionalString get(const StringView &key);
返回值是Optional
,可以表示“非法值/无效值”,如果查询到redis
中为空,则会返回nil
,但是如果使用std::string
来表示,不方便表现这个空值;如果使用std::string*
来表示,是可以用nullptr
表示无效,但是返回指针又设计到内存归谁管。
还有Optional
不支持<<
运算符的重载,需要通过.value()
函数来获取string
。
代码示例:
void test1(sw::redis::Redis &redis)
{cout << "get和set的使用" << endl;redis.flushall(); // 清空数据库,避免残留的数据干扰结果// 使用set设置key-valueredis.set("key1", "111");redis.set("key2", "222");redis.set("key3", "333");redis.set("key4", "444");auto value1 = redis.get("key1");if (value1)cout << "key1:" << value1.value() << endl;auto value2 = redis.get("key2");if (value2)cout << "key2:" << value2.value() << endl;auto value3 = redis.get("key1");if (value3)cout << "key3:" << value3.value() << endl;auto value4 = redis.get("key1");if (value4)cout << "key4:" << value4.value() << endl;
}
exists
判断key
是否存在。
函数原型:
// 版本1
long long exists(const StringView &key);// 版本2
template <typename T>long long exists(std::initializer_list<T> il) {return exists(il.begin(), il.end());}
exists
有两个版本,都是以long long
作为返回值的,这是因为第二个版本可以接受一个初始化列表,可以接收多个key
,有多少个key
就返回多少。
返回值:key 存在的个数。
代码示例:
void test2(sw::redis::Redis &redis)
{cout << "existes的使用" << endl;redis.flushall();redis.set("key1", "111");redis.set("key2", "222");redis.set("key3", "333");auto result1 = redis.exists("key1");cout << "result1:" << result1 << endl;auto result2 = redis.exists("key2");cout << "result2:" << result1 << endl;auto result3 = redis.exists({"key1", "key2", "key3", "key4"});std::cout << "result3:" << result3 << std::endl;
}
del
用户删除key
,函数原型如下:
// 版本1
long long del(const StringView &key);// 版本2
template <typename T>long long del(std::initializer_list<T> il) {return del(il.begin(), il.end());}
代码示例:
void test3(sw::redis::Redis &redis)
{cout << "del的使用" << endl;redis.flushall();redis.set("key1", "111");redis.set("key2", "222");redis.set("key3", "333");auto ret1 = redis.del("key1");cout << ret1 << endl;auto ret2 = redis.del({"key1", "key2", "key3"});cout << ret2 << endl;
}
flushall
清空整个redis
。
函数原型:void flushall(bool async = false);
直接用默认的false
即可。
keys
用于搜索符合条件的key
。
函数原型:
template <typename Output>
void keys(const StringView &pattern, Output output);
第一个参数pattern
是匹配参数,也就是根据某个“特征”寻找匹配的key
,第二个参数output
是一个插入迭代器,用于获取符合条件的key
。
插入迭代器主要有三种:
font_insert_iterator
:用于区间的开头,往前面插入。back_insert_iterator
:区间的末尾,往后面插入。insert_inerator
:区间的任意位置,往该位置之前插入。
对于插入迭代器来说*、++、--
是啥都不干,主要的核心操作就是=
,就是把另一个迭代器,赋值给这个插入迭代器。例如,it
是插入迭代器,it2
是普通的迭代器,当it=it2
,相当于是获取到it2
指向的元素,然后把元素按照it
当前插入迭代器的位置和动作来进行执行插入操作。比如it
是一个back_insert_inerator
,就是把it2
指向的元素插入到it
指向的容器末尾(相当于调用一次push_back
)
在operator=
内部,调用vector.insert()
接口,就能完成插入容器的操作,此时pos
也会自动指向新的位置。
代码示例:
void test4(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");vector<string> ret;auto it = std::back_inserter(ret);redis.keys("*", it);for (auto &r : ret)std::cout << r << std::endl;
}
expire
用于设置超时时间。
函数原型:
bool expire(const StringView &key, long long timeout);
bool expire(const StringView &key, const std::chrono::seconds &timeout);
第一个版本的是long long
类型,以秒为单位,但也可以使用std::chrono::seconds
来控制时间单位。
如果key
不存在返回-2,如果key
存在但是没有超时时间返回-1。
ttl
获取key
剩下的超时时间。
函数原型:long long ttl(const StringView &key);
代码示例:
void test5(sw::redis::Redis &redis)
{cout << "expire和ttl的使用" << endl;redis.flushall();redis.set("key1", "111");redis.set("key2", "222");redis.set("key3", "333");redis.set("key4", "444");redis.expire("key1", 10);redis.expire("key2", std::chrono::seconds(5)); // 设置5秒后过期std::this_thread::sleep_for(5s);cout << redis.ttl("key1") << endl;cout << redis.ttl("key2") << endl;cout << redis.ttl("key3") << endl;cout << redis.ttl("key4") << endl;
}
type
获取key所对应value的数据类型。
函数原型:std::string type(const StringView &key);
代码示例:
void test6(sw::redis::Redis &redis)
{cout << "type的使用" << endl;redis.flushall();redis.set("key1", "111");string ret = redis.type("key1");cout << "key1:" << ret << endl;redis.lpush("key2", "222");ret = redis.type("key2");cout << "key2:" << ret << endl;redis.hset("key3", "aaa", "333");ret = redis.type("key3");cout << "key3:" << ret << endl;redis.sadd("key4", "aaa");ret = redis.type("key4");cout << "key4:" << ret << endl;redis.zadd("key5", "张三", 19);ret = redis.type("key5");cout << "key5:" << ret << endl;
}