一、本文仅做自学笔记用
本文内容参考redis使用c++ API 的hiredis连接详解
C++连接redis数据库需要用到hiredis头文件,最近因为写程序需要用到这方面的知识。上面博文内容较多,难以记忆,打算以这篇文章作为自学笔记,帮助自己理解记忆。
本文对一些函数、结构体等说明,只会挑比较基础、常用或者比较重要的部分,如果想全面了解记得去上面的链接翻看。
二、正文
1.简介
(1)使用redisConnect等函数与redis数据库建立连接,连接信息存储在redisContext结构体中
(2)使用redisCommand()等函数对数据库进行存取(即查询修改等)操作,返回的信息存放在redisReply结构体中
(3)记得redisFree()函数释放redisContext,freeReplyObject(void *reply)函数释放redisReply
2.详解
2.1连接函数
能建立连接,返回redisContext结构体的连接函数有很多种。(可以不用细看有哪些函数)
redisContext *redisConnect(const char *ip, int port);
redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv);
redisContext *redisConnectNonBlock(const char *ip, int port);
redisContext *redisConnectBindNonBlock(const char *ip, int port,const char *source_addr);
redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,const char *source_addr);
redisContext *redisConnectUnix(const char *path);
redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv);
redisContext *redisConnectUnixNonBlock(const char *path);
redisContext *redisConnectFd(int fd);
其中,ip即访问的redis所在ip地址,port为数据库的端口号,还能设置连接等待时间等,连接需求不同可以调用不同的连接函数。
具体的大家看着英文自行理解,或者另外查阅资料。我们最常用的就是第一条函数。
redisContext *redisConnect(const char *ip, int port);
2.2连接返回的指针
调用上面的连接函数,可以返回一个结构体指针,结构体定义如下(可以不用细看结构体内容):
typedef struct redisContext {
int err; /* Error flags, 0 when there is no error错误标志,0表示没有错误 */
char errstr[128]; /* String representation of error when applicable 错误声明 */
int fd;
int flags;
char *obuf; /* Write buffer */
redisReader *reader; /* Protocol reader */
enum redisConnectionType connection_type;
struct timeval *timeout; //设置连接等待时间
struct {
char *host;
char *source_addr;
int port;
} tcp;
struct {
char *path;
} unix_sock;
} redisContext;
我们调用最基本的连接函数以后,返回的redisContext结构体中我们最应该关心的就是err变量,通过它我们就能知道是否连接成功。
2.3完成连接
利用2.1和2.2的内容,我们就可以用简单的几个语句来完成连接了。例子如下:
void BuildConnect(){
redisContext *Connect = redisConnect("127.0.0.1",25244);
if(Connect -> err){//非0则连接失败
cout<<"fail"<<endl;
return;
}
cout<<"success"<<endl;
}
只要err的值为0,就说明我们成功跟指定IP、端口号的数据库建立了连接,连接部分就完成了。(特别说明一下,如果数据库有密码,输密码环节不在连接部分,在下一部分)
2.4redisCommand函数
能对redis数据库执行操作的函数也有很多,在此我就直接使用一个简单的:
void *redisCommand(redisContext *c, const char *format, ...);
先说明一下,这个函数表面上返回的是void,实际上返回的是指向redisReply结构体的指针。
我们使用这个函数就可以直接对进行操作了,接着我们前面的连接代码,我们可以用如下语句对我们连接的数据库操作:
redisCommand(Connect,"set yzz A19190078");
也可以是:
const char * command = "set yzz A19190078";
redisCommand(Connect,command);
两种皆可。
2.5redisReply结构体
我们前面提到,redisCommand函数会返回一个redisReply结构体的指针,这个结构体记录的是对数据库操作以后,数据库反馈给我们的信息,这个信息还是相当重要的。
我们先看看这个结构体的定义:
typedef struct redisReply {
int type; /* REDIS_REPLY_* */
long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
int len; /* Length of string 存储字符串长度 */
char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING 数据库返回的信息*/
size_t elements; /* number of elements, for REDIS_REPLY_ARRAY 如果为数组存储数组长度*/
struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY 存储数组元素向量*/
} redisReply;
大多数时候,我们在对数据库操作以后,数据库都会返回一个OK,或者是我们要查询的信息,如果出错了也会返回错误信息,这些都在char *str这部分体现。
int type的值也是非常重要的:
#define REDIS_REPLY_STRING 1 //存放在char *str
#define REDIS_REPLY_ARRAY 2
#define REDIS_REPLY_INTEGER 3 //integer存储为数据条数
#define REDIS_REPLY_NIL 4
#define REDIS_REPLY_STATUS 5 //成功状态码为:"OK" 存放在char *str
#define REDIS_REPLY_ERROR 6 //存放在char *str
综合2.4和2.5,我们应该写的代码是这样:
redisReply* reply = (redisReply*) redisCommand(Connect,"set yzz A19190078");
freeReplyObject(reply);//千万别忘记释放!
在我们操作完,并且从reply中读取我们需要的信息以后:
千万别忘记释放!千万别忘记释放!千万别忘记释放!
2.6输入密码
这部分其实还是在使用2.5、2.6的内容。
出于安全性,大多数redis数据库都会设置密码,当我们连接完数据库以后,都要输入密码,假设我们前面连接的数据库密码是yzztxdy,那么我们就这样写代码即可:
redisReply* reply = (redisReply*) redisCommand(Connect,"AUTH %s","yzztxdy");
if(reply -> type == REDIS_REPLY_ERROR)
cout<<"fail"<<endl;
else cout<<"success"<<endl;
freeReplyObject(reply);
这样就完成了输密码的功能。
3.小结
这里的内容对我来说暂时已经够用了,之后如果用到了其他的connect、command函数或者有什么注意事项,都会继续回来更新的。