前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言操作redis数据库

C语言操作redis数据库

作者头像
编程珠玑
发布2019-09-03 10:38:32
3.9K0
发布2019-09-03 10:38:32
举报
文章被收录于专栏:编程珠玑

前言

redis(Remote Dictionary Server)是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库--来自维基百科。由于其读写性能高、数据结构丰富、支持主从复制、支持持久化等其他特性,使得redis成为当前最流行的key-value型数据库。本文将简单介绍c语言中如何操作redis数据库。

准备工作

hiredis安装

hiredis是redis官方推荐的基于C接口的客户端组件,它提供接口,供c语言调用以操作数据库。我们需要将hiredis安装到我们的系统中,在redis的源码包的deps/hiredis下就有它的源码,也可以另行下载hiredis 安装方法,进入deps/hiredis目录,执行命令:

代码语言:javascript
复制
make
make install
ldconfig   #使动态库在系统中更新生效
接口介绍
  • 函数原型:redisContext *redisConnect(const char *ip, int port); 说明:该函数用来连接redis数据库,参数为数据库的ip地址和端口,通常默认端口为6379。该函数返回一个redisContext对象。
  • 函数原型:void *redisCommand(redisContext *c, const char *format, …); 说明:该函数执行redis命令,当然也包括由lua脚本组成的命令,返回redisReply对象。
  • 函数原型void freeReplyObject(void *reply); 说明:释放redisCommand执行后返回的redisReply所占用的内存。
  • 函数原型:void redisFree(redisContext *c); 说明:释放redisConnect()所产生的连接。

后面的示例操作基本都是基于以上函数。

  • redis reply对象:
代码语言:javascript
复制
 /* This is the reply object returned by redisCommand() */
 typedef struct redisReply {
     int type; /* 返回结果类型* */
     long long integer; /* 返回类型为整型的时候的返回值 */
     size_t len; /* 字符串长度 */
     char *str; /* 返回错误类型或者字符类型的字符串 */
     size_t elements; /* 返回数组类型时,元素的数量*/
     struct redisReply **element; /* 元素结果集合,redisReply对象 */
 } redisReply;

其中,返回类型有以下几种:

代码语言:javascript
复制
REDIS_REPLY_STRING 1 //字符串
REDIS_REPLY_ARRAY 2    //数组,多个reply,通过element数组以及elements数组大小访问
REDIS_REPLY_INTEGER 3    //整型
REDIS_REPLY_NIL 4    //空,没有数据
REDIS_REPLY_STATUS 5    //状态,str字符串以及len
REDIS_REPLY_ERROR 6    //错误,同STATUS

其他的我们暂时不过多介绍,下面通过一个简单的实例来看看这些接口的基本使用。

实例

实例通过redis数据库的hash表存储以下学生信息:

字段名

含义

sid

学号

name

学生姓名

gender

学生性别

major

专业

c语言描述如下:

代码语言:javascript
复制
#define SID_MAX_LENGHT 16
#define NAME_MAX_LENGHT 16
#define MAJOR_MAX_LENGHT 64
typedef struct Stu_Info_Struct
{
    char sid[SID_MAX_LENGHT];
    char name[NAME_MAX_LENGHT];
    int gender;//0 male,1 female
    char major[MAJOR_MAX_LENGHT];
}Stu_Info_Struct;

程序清单stu_manager.c如下:

代码语言:javascript
复制
/***************************************************************
*   Copyright (C) 2017 All rights reserved.
*
*   文件名称:stu_manager.c
*   创 建 者:hyb
*   创建日期:2017年10月07日
*   描    述:
*
***************************************************************/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<hiredis/hiredis.h>

/*宏定义*/
#define SID_MAX_LENGHT 16
#define NAME_MAX_LENGHT 16
#define MAJOR_MAX_LENGHT 64
#define CMD_MAX_LENGHT  256
#define REDIS_SERVER_IP "127.0.0.1"
#define REDIS_SERVER_PORT 6379
/*结构体定义*/
typedef struct Stu_Info_Struct
{
    char sid[SID_MAX_LENGHT];
    char name[NAME_MAX_LENGHT];
    int gender;//0 male,1 female
    char major[MAJOR_MAX_LENGHT];
}Stu_Info_Struct;

typedef enum STU_RESULT
{
    SUCCESS=0,
    FAILURE=1
}STU_RESULT;

/*函数*/
STU_RESULT addStu(Stu_Info_Struct *stu);/*添加信息*/
/*执行命令*/
STU_RESULT exeRedisIntCmd(char *cmd);
STU_RESULT quryStuBySid(char *sid);
STU_RESULT exeRedisStrCmd(char *cmd);
/**************************************
函数名:addStu
函数功能:添加学生信息
输入参数:stu 学生信息结构指针
输出参数:
返回值:STU_RESULT  成功或失败
************************************/
STU_RESULT addStu(Stu_Info_Struct *stu)
{
    char cmd[CMD_MAX_LENGHT] = {0};
    /*检查入参*/
    if(NULL == stu)
    {
        printf("NULL pointer");
        return FAILURE;
    }
    /*组装redis命令*/
    snprintf(cmd,CMD_MAX_LENGHT,"hset stu:%s name %s gender %d major %s",
            stu->sid,stu->name,stu->gender,stu->major);

    /*执行redis命令*/
    if(FAILURE == exeRedisIntCmd(cmd))
    {
        printf("add student %s,%s,%d,%s failure\n",stu->sid,stu->name,stu->gender,stu->major);
        return FAILURE;
    }
    printf("add student %s,%s,%d,%s success\n",stu->sid,stu->name,stu->gender,stu->major);
    return SUCCESS;
}
/**************************************
函数名:exeRedisIntCmd
函数功能:执行redis 返回值为int类型命令
输入参数:cmd  redis命令
输出参数:redis 返回结构
返回值:STU_RESULT
*************************************/
STU_RESULT exeRedisIntCmd(char *cmd)
{
    /*检查入参*/
    if(NULL == cmd)
    {
        printf("NULL pointer");
        return FAILURE;
    }
    /*连接redis*/
    redisContext *context = redisConnect(REDIS_SERVER_IP,REDIS_SERVER_PORT);
    if(context->err)
    {
        redisFree(context);
        printf("%d connect redis server failure:%s\n",__LINE__, context->errstr);
        return FAILURE;
    }
    printf("connect redis server success\n");

    /*执行redis命令*/
    redisReply *reply = (redisReply *)redisCommand(context, cmd);
    if(NULL == reply)
    {
        printf("%d execute command:%s failure\n",__LINE__,cmd);
        redisFree(context);
        return FAILURE;
     }
    //返回执行结果为整型的命令,只有状态为REDIS_REPLY_INTEGER,并且INTEGER是大于0时,才表示这种类型的命令执行成功
    if(!(reply->type == REDIS_REPLY_INTEGER && reply->integer > 0))
    {
        printf("%d execute command:%s failure\n",__LINE__, cmd);
        freeReplyObject(reply);
        redisFree(context);
        return FAILURE;
    }

    freeReplyObject(reply);
    redisFree(context);
    printf("%d execute command:%s success\n",__LINE__,cmd);
    return SUCCESS;

}
/**************************************
函数名:quryStuBySid
函数功能:通过sid查询学生信息
输入参数:cmd  redis命令
输出参数:redis 返回结构
返回值:STU_RESULT
*************************************/
STU_RESULT queryStuBySid(char *sid)
{
    char cmd[CMD_MAX_LENGHT] = {0};
    /*入参检查*/
    if(NULL == sid)
    {
        printf("%d NULL pointer\n",__LINE__);
        return FAILURE;
    }
    /*组装执行命令*/
    snprintf(cmd,CMD_MAX_LENGHT,"HGETALL stu:%s",sid);
    if(FAILURE == exeRedisStrCmd(cmd))
    {
        printf("%d query stu failue",__LINE__);
        return FAILURE;
    }
    return SUCCESS;
}
STU_RESULT exeRedisStrCmd(char *cmd)
{

    /*检查入参*/
    if(NULL == cmd)
    {
        printf("NULL pointer");
        return FAILURE;
    }

    /*连接redis*/
    redisContext *context = redisConnect(REDIS_SERVER_IP,REDIS_SERVER_PORT);
    if(context->err)
    {
        redisFree(context);
        printf("%d connect redis server failure:%s\n",__LINE__, context->errstr);
        return FAILURE;
    }
    printf("connect redis server success\n");

    /*执行redis命令*/
    redisReply *reply = (redisReply *)redisCommand(context, cmd);
    if(NULL == reply)
    {
        printf("%d execute command:%s failure\n",__LINE__,cmd);
        redisFree(context);
        return FAILURE;
     }
    //返回执行结果为整型的命令,只有状态为REDIS_REPLY_INTEGER,并且INTEGER是大于0时,才表示这种类型的命令执行成功
    if(!(reply->type == REDIS_REPLY_ARRAY && reply->elements > 0))
    {
        printf("%d execute command:%s failure\n",__LINE__, cmd);
        freeReplyObject(reply);
        redisFree(context);
        return FAILURE;

    }

    printf("%d,%lu\n",reply->type,reply->elements);
    int i = 0;
    for(i=0;i < reply->elements;i++)
    {
        if(i%2 ==0)
        {
            printf("%s:",reply->element[i]->str);
        }
        else
        {

            printf("%s\n",reply->element[i]->str);
        }
    }
    freeReplyObject(reply);
    redisFree(context);
    return SUCCESS;
}
int main(int argc,char *argv[])
{
    Stu_Info_Struct stu =
    {
     "01",
     "hu",
    1,
    "CS"
    };

    addStu(&stu);
    queryStuBySid("01");
    return 0;
}
编译代码
代码语言:javascript
复制
gcc -g stu_manager.c -o stu -lhiredis

可能遇到问题:

代码语言:javascript
复制
libhiredis.so.0.10: cannot open shared object file: No such file or directory

/usr/lib/hiredis目录下没有hiredis库,将编译链接好的hiredis库拷贝到/usr/lib/hiredis目录下,并且执行命令重新加载配置:

代码语言:javascript
复制
ldconfig
启动redis服务器
代码语言:javascript
复制
redis-server
运行
代码语言:javascript
复制
./stu

运行结果:

代码语言:javascript
复制
hyb@ubuntu-16:redis# ./stu
connect redis server success
116 execute command:hset stu:01 name hu gender 1 major CS success
add student 01,hu,1,CS success
connect redis server success
2,6
name:hu
gender:1
major:CS

程序首先将学生信息添加到数据库中,然后通过id将其结果查询出来。

总结

本文对hiredis的接口进行了简单的介绍,并通过一个小实例说明了这些接口在c中的使用。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-09-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程珠玑 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 准备工作
  • hiredis安装
    • 接口介绍
    • 实例
      • 编译代码
        • 启动redis服务器
          • 运行
          • 总结
          相关产品与服务
          云数据库 Redis®
          腾讯云数据库 Redis®(TencentDB for Redis®)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档