C++来操作redis数据库。通过hiredis.h接口来实现,目前只能在Linux环境使用。 该命令回复了状态回复。可以使用访问状态字符串reply->str。可以使用访问此字符串的长度reply->len。 为了解释 更多用法请点击:https://github.com/redis/hiredis
Linux下使用C++操作redis数据库
文章目录
一、安装配置hiredis.h
下载hiredis.h
hiredis.h 的下载地址为:
https://github.com/redis/hiredis配置环境变量
git clone完hiredis.h后,进入hiredis目录当中
cd hiredis
make && make install
(自动把libhiredis.so放到/usr/local/lib/中,把hiredis.h放到/usr/local/inlcude/hiredis/中
)make && make install
#include <hiredis/hiredis.h>
即可编译代码的时候需要加链接的库及库的路径
,假设文件为redis.cpp,那么编译命令如下g++ redis.cpp -o redis -L/usr/local/lib/ -lhiredis
如果出现动态库无法加载
,那么需要进行如下配置sudo vim /etc/ld.so.conf.d/usr-libs.conf
sudo /sbin/ldconfig
二、接口介绍
1.
建立链接:redisConnect
redisContext* redisConnect(const char *ip, int port)
函数解释
当连接处于错误状态时,该redisContext 结构具有一个err非零的整数字段
。该字段errstr将包含带有错误描述的字符串。应检查该err字段以查看建立连接是否成功
还提供了一个函数,供连接超时限定
,即redisContext* redisConnectWithTimeout(const char *ip, int port, timeval tv)。
注意注意,官方说明redisConnect函数不是线程安全的
使用案例
redisContext *c = redisConnect("127.0.0.1", 6379); if (c == NULL || c->err) { if (c) { printf("Error: %sn", c->errstr); // handle error } else { printf("Can't allocate redis contextn"); } }
错误解释
函数调用不成功时,取决于函数NULL还是REDIS_ERR
返回。err上下文中的字段将为非零值,并设置为以下常量之一:2.
执行redis命令:redisCommand
void *redisCommand(redisContext *c, const char *format...)
函数解释
第一个参数为连接数据库返回的redisContext,剩下的参数为变参
,如同C语言中的prinf()函数。使用案例
首先介绍的是 redisCommand。此函数采用类似于printf的格式。最简单的形式是这样使用: reply = redisCommand(context, "SET foo bar"); 说明%s符在命令中插入一个字符串,并用于strlen确定字符串的长度: reply = redisCommand(context, "SET foo %s", value); 当您需要在命令中传递二进制安全字符串时,%b可以使用说明符。与指向字符串 的指针一起,它需要字符串的size_tlength参数: reply = redisCommand(context, "SET foo %b", value, (size_t) valuelen); 在内部,Hiredis将命令拆分为不同的参数,并将其转换为用于与Redis通信 的协议。一个或多个空格分隔参数,因此您可以在参数的任何位置使用说明符: reply = redisCommand(context, "SET key:%s %s", myid, value);
void * redisCommandArgv(redisContext * c,int argc, const char ** argv,const size_t * argvlen);
函数解释
argc字符串数组argv和参数的长度argvlen
。argvlen可以将设置为NULL,并且函数将strlen(3)在每个参数上使用以确定其长度。
返回值的语义与相同redisCommand。
3.
释放redisCommand
void freeReplyObject(void *reply)
函数解释
成功执行命令后,的返回值将保留
答复。发生错误时,返回值为NULL并且err将设置上下文中的字段
。返回错误后,上下文context将无法重用,您应该建立一个新的连接。
多批量回复中的每个元素也是一个redisReply对象,可以通过访问reply->element[..index..]。
应该使用freeReplyObject()函数释放答复
。请注意,此函数将负责释放数组和嵌套数组中包含的子答复对象,因此用户无需释放子答复(这实际上是有害的,并且会破坏内存)。4.
断开连接:redisFree
void redisFree(redisContext *c)
关闭套接字
,然后释放在创建上下文时完成的分配。5.流水线:Pipelining
Hiredis如何支持阻塞连接中的流水线操作
,需要了解内部执行流程。
Hiredis首先根据Redis协议格式化命令。
将格式化的命令放入上下文的输出缓冲区
中。此输出缓冲区是动态
的,因此它可以容纳任意数量的命令。将命令放入输出缓冲区后,将redisGetReply被调用
。该函数具有以下两个执行路径:输入缓冲区为非空:
输入缓冲区为空:
void redisAppendCommand(redisContext * c,const char * format,...); void redisAppendCommandArgv(redisContext * c,int argc, const char ** argv,const size_t * argvlen);
redisGetReply可用于接收后续答复
。函数的返回值是REDIS_OK或REDIS_ERR,其中后者表示读取答复时发生错误。就像其他命令一样,err上下文中的字段可用于找出导致此错误的原因
。redisReply *reply; redisAppendCommand(context,"SET foo bar"); redisAppendCommand(context,"GET foo"); redisGetReply(context,(void *)&reply); // reply for SET freeReplyObject(reply); redisGetReply(context,(void *)&reply); // reply for GET freeReplyObject(reply);
reply = redisCommand(context,"SUBSCRIBE foo"); freeReplyObject(reply); while(redisGetReply(context,(void *)&reply) == REDIS_OK) { // consume message freeReplyObject(reply); }
三、简单封装hiredis
#ifndef __REDIS_HANDLER_H__ #define __REDIS_HANDLER_H__ #include <hiredis/hiredis.h> #include <string> using namespace std; enum { M_REDIS_OK = 0, //执行成功 M_CONNECT_FAIL = -1, //连接redis失败 M_CONTEXT_ERROR = -2, //RedisContext返回错误 M_REPLY_ERROR = -3, //redisReply错误 M_EXE_COMMAND_ERROR = -4 //redis命令执行错误 }; class RedisHandler { public: RedisHandler(); ~RedisHandler(); int connect(const string &addr, int port, const string &pwd = ""); //连接redis数据库:addr:IP地址,port:端口号,pwd:密码(默认为空) int disConnect(); //断开连接 int setValue(const string &key, const string &value); //添加或修改键值对,成功返回0,失败<0 int getValue(const string &key, string &value); //获取键对应的值,成功返回0,失败<0 int delKey(const string &key); //删除键,成功返回影响的行数,失败<0 int printAll(); //打印所有的键值对 string getErrorMsg(); //获取错误信息 private: string m_addr; //IP地址 int m_port; //端口号 string m_pwd; //密码 redisContext* pm_rct; //redis结构体 redisReply* pm_rr; //返回结构体 string error_msg; //错误信息 int connectAuth(const string &pwd); //使用密码登录 int handleReply(void* value = NULL, redisReply ***array = NULL); //处理返回的结果 }; #endif
#include "redis_handler.h" #include <string> #include <cstring> #include <iostream> using namespace std; RedisHandler::RedisHandler() { m_addr = ""; m_port = 0; m_pwd = ""; pm_rct = NULL; pm_rr = NULL; error_msg = ""; } RedisHandler::~RedisHandler() { disConnect(); pm_rct = NULL; pm_rr = NULL; } /* 连接redis数据库 addr: 地址,port:端口号,pwd:密码 成功返回M_REDIS_OK,失败返回M_CONNECT_FAIL */ int RedisHandler::connect(const string &addr = "127.0.0.1", int port = 6379, const string &pwd) { m_addr = addr; m_port = port; m_pwd = pwd; pm_rct = redisConnect(m_addr.c_str(), m_port); if (pm_rct->err) { error_msg = pm_rct->errstr; return M_CONNECT_FAIL; } if (!m_pwd.empty()) { return connectAuth(m_pwd); } return M_REDIS_OK; } /* 断开redis连接 */ int RedisHandler::disConnect() { redisFree(pm_rct); freeReplyObject(pm_rr); } /* 添加或插入键值对 key:键,value:值 成功返回M_REDIS_OK,失败返回<0 */ int RedisHandler::setValue(const string &key, const string &value) { string cmd = "set " + key + " " + value; pm_rr = (redisReply*)redisCommand(pm_rct, cmd.c_str()); return handleReply(); } /* 获取键对应的值 key:键,value:值引用 成功返回M_REDIS_OK,失败返回<0 */ int RedisHandler::getValue(const string &key, string &value) { string cmd = "get " + key; pm_rr = (redisReply*)redisCommand(pm_rct, cmd.c_str()); int ret = handleReply(&value); } /* 删除键 key:键 成功返回影响的行数(可能为0),失败返回<0 */ int RedisHandler::delKey(const string &key) { string cmd = "del " + key; pm_rr = (redisReply*)redisCommand(pm_rct, cmd.c_str()); int rows = 0; int ret = handleReply(&rows); if (ret == M_REDIS_OK) return rows; else return ret; } /* 打印所有键值对到屏幕上 */ int RedisHandler::printAll() { string cmd = "keys *"; pm_rr = (redisReply*)redisCommand(pm_rct, cmd.c_str()); int len ; redisReply **array; int ret = handleReply(&len, &array); if (ret == M_REDIS_OK) { for (int i = 0; i < len; i++) cout << string(array[i]->str) << endl; } else return 0; } /* 返回错误信息 */ string RedisHandler::getErrorMsg() { return error_msg; } /* 使用密码登录 psw:登录密码 成功返回M_REDIS_OK,失败返回<0 */ int RedisHandler::connectAuth(const string &psw) { string cmd = "auth " + psw; pm_rr = (redisReply*)redisCommand(pm_rct, cmd.c_str()); return handleReply(); } /* 处理redis返回的信息 value:数据指针,用于保存redis返回的基本类型(value指针指向该数据) array:数组指针,用于保存redis返回的数组 成功返回M_REDIS_OK,失败返回<0 */ int RedisHandler::handleReply(void* value, redisReply*** array) { if (pm_rct->err) { error_msg = pm_rct->errstr; return M_CONTEXT_ERROR; } if (pm_rr == NULL) { error_msg = "auth redisReply is NULL"; return M_REPLY_ERROR; } switch (pm_rr->type) { case REDIS_REPLY_ERROR: error_msg = pm_rr->str; return M_EXE_COMMAND_ERROR; case REDIS_REPLY_STATUS: if (!strcmp(pm_rr->str, "OK")) return M_REDIS_OK; else { error_msg = pm_rr->str; return M_EXE_COMMAND_ERROR; } case REDIS_REPLY_INTEGER: *(int*)value = pm_rr->integer; return M_REDIS_OK; case REDIS_REPLY_STRING: *(string*)value = pm_rr->str; return M_REDIS_OK; case REDIS_REPLY_NIL: *(string*)value = ""; return M_REDIS_OK; case REDIS_REPLY_ARRAY: *(int*)value = pm_rr->elements; *array = pm_rr->element; return M_REDIS_OK; default: error_msg = "unknow reply type"; return M_EXE_COMMAND_ERROR; } }
#include <iostream> #include <string> #include "redis_handler.h" using namespace std; int main() { RedisHandler* rh = new RedisHandler(); int ret; //连接测试 cout << "错误测试: " << "地址错误" << endl; ret = rh->connect("34.15.14.15", 6379, "linesum"); if (ret != M_REDIS_OK) cout << "redis error: " << rh->getErrorMsg() << endl; cout << "错误测试: " << "端口错误" << endl; ret = rh->connect("127.0.0.1", 1234, "linesum"); if (ret != M_REDIS_OK) cout << "redis error: " << rh->getErrorMsg() << endl; cout << "错误测试: " << "密码错误" << endl; ret = rh->connect("127.0.0.1", 6479, "linsum"); if (ret != M_REDIS_OK) cout << "redis error: " << rh->getErrorMsg() << endl; ret = rh->connect("127.0.0.1", 6479, "linesum"); if (ret != M_REDIS_OK) { cout << "redis error: " << rh->getErrorMsg() << endl; return ret; } //set测试 cout << "错误测试: " << "set不带value参数" << endl; ret = rh->setValue("key11", ""); if (ret != M_REDIS_OK) cout << "redis error: " << rh->getErrorMsg() << endl; ret = rh->setValue("key11", "value11"); if (ret != M_REDIS_OK) { cout << "redis error: " << rh->getErrorMsg() << endl; return ret; } ret = rh->setValue("key22", "value22"); if (ret != M_REDIS_OK) { cout << "redis error: " << rh->getErrorMsg() << endl; return ret; } //get测试 string str; cout << "错误测试: " << "get不带key参数" << endl; ret = rh->getValue("key1111", str); if (ret != M_REDIS_OK) cout << "redis error: " << rh->getErrorMsg() << endl; ret = rh->getValue("key11", str); if (ret != M_REDIS_OK) { cout << "redis error: " << rh->getErrorMsg() << endl; return ret; } else cout << "value : " << str << endl; //print测试 ret = rh->printAll(); if (ret != M_REDIS_OK) { cout << "redis error: " << rh->getErrorMsg() << endl; return ret; } //del测试 cout << "错误测试: " << "删除不存在的key" << endl; ret = rh->delKey("key1111"); if (ret != M_REDIS_OK) cout << "redis error: " << rh->getErrorMsg() << endl; ret = rh->delKey("key11"); if (ret != M_REDIS_OK) { cout << "redis error: " << rh->getErrorMsg() << endl; return ret; } delete rh; return 0; }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算