hiredis使用,封装代码示例

简言

1. c++下使用redis的话,hiredis是首选,封装得好,接口简单

2. redis的下载和编译请参考笔者的这篇博客,等待

3. hiredis的编译请参考笔者的这篇博客,等待

4. hiredis有个很大的优点就是可以直接保存,读取结构体,简直不要太爽,不像go语言那种渣渣,只能保存字符串,想保存一个结构体时要把结构体序列化成字符串,比如转成json字符串再保存,太麻烦

代码下载地址

linux版:https://download.csdn.net/download/yzf279533105/11979214

windows版:代码都一样,没时间写哈

接口和结构

我们这里先了解一下hiredis的基本接口,笔者都加了注释

// 连接数据库,只是连接,并未认证,认证可以通过redisCommand执行命令来实现
redisContext *redisConnect(const char *ip, int port);

// 执行命令,注意:redisCommand(),redisCommandArgv() 的返回值其实是 redisReply* 类型
void *redisCommand(redisContext *c, const char *format, ...);
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);

//释放资源
void freeReplyObject(void *reply);
void redisFree(redisContext *c);

// 执行命令的结果,注意:只要返回值不为空,就一定要释放,不然会有内存泄漏
typedef struct redisReply 
{
    /*执行结果的类型*/
    int type;
    /*执行结果为整数时,存储返回值*/
    long long integer;
    /*执行结果为string或error时,存储字符串的长度*/
    size_t len;
    /*执行结果是string或error时,存储返回值*/
    char *str;
    /*执行结果是数组时,表数组中元素的个数*/
    size_t elements;
    /*执行结果是数组时,存储元素*/
    struct redisReply **element;
} redisReply;

接口封装

注:笔者的感觉是只要支持了struct整体的保存和读取,也就支持了大部分的读写需求,比如string, hash对象,没必要了

对吧,有了保时捷,还要啥自行车,至于list set zset等结构体,等有需求的时候再封装,那时候会更新博客滴

1. 初始化,并连接及认证,成功返回true, 失败返回false

// 初始化
// IP    	:	redisIP地址
// port  	:	redis端口号
// password     :	redis的认证密码
// timeout	:	超时时间
bool Init(string IP, int port, string password, int timeout=5000);

2. 执行命令的接口

// 判断指定key是否存在
bool Exist(string key);

// 设置指定key的值,过期时间单位:秒
int Set(string key, string val, uint32_t expire);

// 获取指定key的值,字符串类型
string Get(string key);

// 设置指定key的值,bin类型
// pVal		:	内存地址
// len		:	内存大小
// expire	:	过期时间,单位:秒
int Set(string key, const char* pVal, int length, uint32_t expire);

// 获取指定key的值,bin类型
int Get(string key, CAutoRedisReply& reply);

实验结果如图(这里只实验了string和结构体的保存,读取)

测试代码如下

#include <stdio.h>
#include <string.h>
#include <iostream>
#include "redis_client.h"
using namespace std;


// 测试结构体,里面有各种类型的字段,但是不能有string类型,必须要能整体拷贝
struct SStruct
{
	SStruct()
	{
		memset(this,0,sizeof(*this));
	}

	int 	a;
	float 	b;
	char	c[20];
	char 	d;
};

int main()
{
	// redis连接实例
	CRedisClient m_redisClient;

	// redis配置,应该写在配置文件中读取,这里只是简单演示
	string IP 	= "192.168.11.177";
	int    port 	= 6379;
	string password = "yzf279533105";
	int    timeout  = 5000;

	// 初始化,并建立连接
	if(!m_redisClient.Init(IP,port,password,timeout))
	{
		printf("main(), Init() failed");
		return -1;
	}

	/////////////////////////////// Set测试 string类型  /////////////////////////////////////
	string key = "key_1";
	string val = "value_1";
	int result = m_redisClient.Set(key, val, 30);
	if(result != REDIS_SUCCESS)
	{
		printf("main(), Set(string) failed");
		return -1;
	}
	printf("main(), Set(string), success, key=%s, value=%s \n", key.c_str(), val.c_str());

	////////////////////////////// Get测试 string类型  //////////////////////////////////////
	string value = m_redisClient.Get(key);
	printf("main(), Get(string), success, key=%s, value=%s \n", key.c_str(), value.c_str());


	/////////////////////////////  Set测试 结构体类型  //////////////////////////////////////
	SStruct s1;
	s1.a = 321;
	s1.b = 3.14159;
	strcpy(s1.c,"hello world!");
	s1.d = 'a';
	
	string key2 = "struct:1";
	result = m_redisClient.Set(key2, (char*)&s1, sizeof(SStruct), 100);
	if(result != REDIS_SUCCESS)
	{
		printf("main(), Set(struct) failed");
		return -1;
	}
	printf("main(), Set(struct), success, key2=%s \n", key2.c_str());

	////////////////////////////// Get测试 结构体类型  //////////////////////////////////////
	CAutoRedisReply reply;
	result = m_redisClient.Get(key2, reply);
	if(result != REDIS_SUCCESS)
	{
		printf("main(), Get(struct), failed");
		return -1;
	}
	redisReply* replyPtr = reply.get();
	SStruct s2;
	// 整体拷贝给s2结构体即可
	memcpy(&s2, replyPtr->str,sizeof(SStruct));
	printf("main(), Get(struct), success, s2.a=%d, s2.b=%f, s2.c=%s, s2.d=%c \n", s2.a, s2.b, s2.c, s2.d);

	getchar();
	return 0;
}
发布了105 篇原创文章 · 获赞 58 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/yzf279533105/article/details/102960886