C++学习记录:C++连接Redis数据库

Posted 河边小咸鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++学习记录:C++连接Redis数据库相关的知识,希望对你有一定的参考价值。

C++学习记录:C++连接Redis数据库

  之前学习了Redis数据库相关的内容,但是并没有在编写C++代码中用到Redis相关内容。
  本篇笔记记录了个人在 Linux 环境下使用 C++ 连接 Redis 数据库的过程。实现了一个简单的排行榜功能。
  由于现在的主流是使用 java 连接 redis,所以在网上查询 C语言 的API消耗了一部分时间,在本篇笔记中,我将记录相关数据结构和API的使用方法。


一、基础准备

1. 找到hiredis.h

  一般来讲,这个文件在你的redis文件夹下deps/hiredis目录中。将其include到源码中即可使用redis的API。
在这里插入图片描述

2. 编译并且连接库

  此时可以尝试写一个基础代码,随后编译。例如:

/*此文件位于redis文件夹下 test.cpp*/
#include"deps/hiredis/hiredis.h"

int main()
{

	return 0;
}

  随后编译:

g++ test.cpp -o test -l hiredis

  若可以正常编译,则说明没问题。若是提示找不到hiredis库文件,则按下面进行操作:

//首先进入redis文件夹中,安装
# cd redis-x.x.xx
# make
# make install
//随后进入 redis/deps/hiredis 文件夹中,安装
# cd deps/hiredis/
# make
# make install

  随后即可正常编译。

3. 运行

  找到上面编译生成的文件,运行,若成功执行即可跳过本节内容。
  若提示找不到链接文件,则说明动态库无法被正确连接。则按下面步骤操作:

//进入动态库链接文件
# vim /etc/ld.so.conf
//在新的一行中加入库文件所在目录
添加: .../redis-x.x.x/deps/hiredis
//更新/etc/ld.so.cache文件
# ldconfig

  随后即可正常运行编译生成的文件。

二、代码相关

1. 常用

  • 建立redis连接
redisContext* myredis = redisConnect("127.0.0.1",6379);
/*
如果 myredis->err = true,则说明连接失败
字符串 myredis->errstr 即为失败原因
*/
  • 执行redis语句并接收结果
redisReply* reply = (redisReply*)redisCommand(myredis, "set zzz 1");
/*
语句执行的结果,储存在 redisReply结构体类型 的 reply 中
*/
  • 释放reply结构体
freeReplyObject(reply);
  • 断开redis连接
redisFree(myredis);

2. redisReply结构体

  我感觉这算是redis相关内容中比较重要的内容了,语句执行的结果全在这个结构体中。

  • 下面是这个结构体的定义:
typedef struct redisReply {
    int type; /* 返回值类型 */
    long long integer; /* 当返回类型为 REDIS_REPLY_INTEGER 时 */
    size_t len; /* 返回的字符串长度 */
    char *str; /* 当返回值类型为 REDIS_REPLY_ERROR 和 REDIS_REPLY_STRING */
    size_t elements; /* 返回的数组长度 */
    struct redisReply **element; /* 当返回值类型为 REDIS_REPLY_ARRAY */
} redisReply;
  • type的类型
REDIS_REPLY_STRING: 1 
REDIS_REPLY_ARRAY: 2
REDIS_REPLY_INTEGER:3 
REDIS_REPLY_NIL: 4
REDIS_REPLY_STATUS: 5
REDIS_REPLY_ERROR: 6

我们首先通过type来确认返回值的类型:

  1. 返回值为1即为字符串,通过reply->str获取。
  2. 返回值为2即为数组,通过reply->element获取到redisReply数组,再遍历该数组,通过type正确获取其中信息。
  3. 返回值为3即为数字,通过reply->integer获取。
  4. 返回值为4即为空。
  5. 返回值为5即为执行语句的状态,通过reply->str获取,若结果为"OK"即为成功执行。
  6. 返回值为6即为执行错误。

  返回值的类型和执行语句的类型是相关的,例如我执行get命令,则type应该为1;若我执行zrevrange命令,则type应该为2。在下文中,我简单实现了一个排行榜功能,其中使用的结构为sorted_set,则其返回的排行榜结果type应为2,通过遍历其element数组,即可获取排行榜信息。

三、一个简单的排行榜demo

1. 思路

  简单来说就是获取key和范围,使用sprintf拼接redis查询语句,通过返回的redisReply结构体输出结果。

2. 代码

#include<iostream>
#include<stdio.h>
#include"deps/hiredis/hiredis.h"
using namespace std;

redisContext* myredis = new redisContext;
redisReply* reply = new redisReply;
char query[150];//查询语句  

void get_rank(const char* key_name, int start, int stop)
{
    sprintf(query, "zrevrange %s %d %d", key_name, start, stop);
    reply = (redisReply *)redisCommand(myredis, query);
    //printf("命令执行结果 reply type: %d\\n", reply->type);
    if (reply->type == 2)
    {
        for(int i=0;i<reply->elements;i++)
        {
            if(reply->element[i]->type != 1)
            {
                printf("Error-Please check that the input is correct\\n");
                freeReplyObject(reply);
                return;
            }
            if(i == 0)
            {
                printf("\\nRANK:\\n|----------|\\n");
            }
            printf("| %2d -- %2s |\\n", i+1, reply->element[i]->str);
        }
        printf("|----------|\\n\\n");
    }
    else
    {
        printf("Error-Please check that the input is correct\\n");
    }
    freeReplyObject(reply);
}

void get_rank_withscores(const char* key_name, int start, int stop)
{
   	sprintf(query, "zrevrange %s %d %d withscores", key_name, start, stop);
    reply = (redisReply *)redisCommand(myredis, query);
    //printf("命令执行结果 reply type: %d\\n", reply->type);
    if (reply->type == 2)
    {
        for(int i=0;i<reply->elements;i+=2)
        {
            if(reply->element[i]->type != 1)
            {
                printf("Error-Please check that the input is correct\\n",reply->element[i]->type);
                freeReplyObject(reply);
                return;
            }
            if(i == 0)
            {
                printf("\\nRANK:\\n|-----------------|\\n");
            }
            printf("| %2d -- %2s -- %3s |\\n", i/2+1, reply->element[i]->str, reply->element[i+1]->str);
        }
        printf("|-----------------|\\n\\n");
    }
    else
    {
        printf("Error-Please check that the input is correct\\n");
	}
    freeReplyObject(reply);
}

int main()
{
    myredis = redisConnect("127.0.0.1",6379);
    if(myredis->err)//if error
    {
        cout << "Connection Error:" << myredis->errstr << endl;
    }
    
	//查询key:score的前十名
    get_rank("score", 0, 9);
    
    //查询key:score的前十名 并且带上分数
    get_rank_withscores("score", 0 ,9);

    redisFree(myredis);
    return 0;
}

3. 执行结果

(上为不带分数 下为带分数)
在这里插入图片描述

以上是关于C++学习记录:C++连接Redis数据库的主要内容,如果未能解决你的问题,请参考以下文章

QT 实用代码片段

C++ 解释器/控制台/片段编译器

linux下C++连接redis

这些 C++ 代码片段有啥作用?

以下代码片段 C++ 的说明

有趣的 C++ 代码片段,有啥解释吗? [复制]