前言

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

准备工作

hiredis安装

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

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对象:
 /* 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;

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

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语言描述如下:

#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 femalechar major[MAJOR_MAX_LENGHT];
}Stu_Info_Struct;

程序清单stu_manager.c如下:


/***************************************************************
*   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 femalechar 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;
}

编译代码

gcc -g stu_manager.c -o stu -lhiredis

可能遇到问题:

libhiredis.so.0.10: cannot open shared object file: No such file or directory

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

ldconfig

启动redis服务器

redis-server

运行

./stu

运行结果:

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中的使用。本文最新内容地址:C语言操作redis数据库

微信公众号:编程珠玑

c语言操作redis数据库相关推荐

  1. c语言连接数据库例子,c语言操作mysql数据库小例子_互帮互助(C language MySQL database operation example _ mutual help).doc...

    这是精心收集的精品经典资料,值得下载保存阅读! c语言操作mysql数据库小例子_互帮互助(C language MySQL database operation example _ mutual h ...

  2. zincrby redis python_【Redis数据结构 序】使用redispy操作Redis数据库

    点击蓝色"不太灵光的程序员"关注我哟加个"星标",每天上午 08:00,干货推送!本文依旧会对学习内容进行拆分,建议阅读时间基本保持10分钟内,想学习之前章节内 ...

  3. Django中pipeline操作Redis数据库

    1.Redis的 C - S 架构: 基于客户端-服务端模型以及请求/响应协议的TCP服务. 客户端向服务端发送一个查询请求,并监听Socket返回. 通常是以阻塞模式,等待服务端响应. 服务端处理命 ...

  4. Linux下使用C++操作redis数据库

    Linux下使用C++操作redis数据库 文章目录 Linux下使用C++操作redis数据库 一.安装配置hiredis.h 二.接口介绍 1.**`建立链接:redisConnect`** 2. ...

  5. go语言mysql操作_使用Go语言操作MySQL数据库的思路与步骤

    最近在做注册登录服务时,学习用Go语言操作MySQL数据库实现用户数据的增删改查,现将个人学习心得总结如下,另外附有代码仓库地址,欢迎各位有兴趣的fork. 软件环境:Goland.Navicat f ...

  6. java mysql nclob_java语言操作Oracle数据库中的CLOB数据类型 (转)

    java语言操作Oracle数据库中的CLOB数据类型 (转)[@more@] 有关字段类型的相关信息可以查阅oracle技术网.下面摘抄一些有关blob.clob等类型的说明.又便于大家的了解. 字 ...

  7. zincrby redis python_【Redis数据结构 序】使用redis-py操作Redis数据库

    想要看更加舒服的排版.更加准时的推送 关注公众号"不太灵光的程序员" 每日八点有干货推送 同时发布<[Redis数据结构 1序]1使用redis-py操作Redis数据库&g ...

  8. C/C++编程操作Redis数据库,hiredis包装redis数据库操作接口及测试(增删改查与连接)

    介绍一个实际应用场景,对于客户频繁需要查询的信息,可以将其放在redis内存数据库中,相当于一个缓存,每次查的时候先去redis内存数据库中去查询,如果查询不到再去oracle数据库中查询,这样提高了 ...

  9. Linux C语言操作SQLite数据库

    1. SQLite数据库特点 (1)SQLite数据库是开源的嵌入式数据库,无需独立的数据库引擎,直接嵌入到应用程序进程中,因此,通过API,应用程序可以直接操作它. (2)事务的处理是原子的,一致的 ...

最新文章

  1. 实验二 164 张增进
  2. 从 no-code 到 low-code 再到 pro-code
  3. 疫情影响全景图:疫情对各行业短中期影响!
  4. c++ 如何给 “运行中“ 的线程传递数据;
  5. 使用Java第2部分查询DynamoDB项
  6. PID控制器改进笔记之四:改进PID控制器之设定值响应
  7. 【OpenCV学习笔记】2.1OpenCV基本数据类型
  8. 【Unity】UGUI无法修改字体大小
  9. MySQL抛出 Lock wait timeout exceeded; try restarting transaction
  10. 简书优秀IT专栏作者推荐
  11. oracle 偶尔登录超时,OracleClient,间歇性连接问题:应用程序挂起在OracleConnection.Open()上,没有超时,没有引发异常...
  12. 渗透测试专业人员使用的11种工具
  13. 域名注册必须实名认证 《互联网域名管理办法》11月1日实施
  14. CentOS 8 更新/etc/yum.repos.d
  15. loadrunnner3
  16. Icon Font的转换
  17. ioa的app开发和android区别,ioA 7000
  18. 云+AI技术助攻,智慧酒店原来是这样的!
  19. 【5G系列】AS层的网络选择(3)——小区重选标准
  20. 火车头定制规则php什么意思,javascript - 请教一个火车头采集器可用的纯正规则!...

热门文章

  1. 基于docker的hadoop集群搭建
  2. js 最新手机号码、电话号码正则表达式
  3. 多屏互动linux电脑,大神教你玩转多屏互动-PC投屏安卓篇
  4. 2020面试美团的朋友看过来,牛客网搜集整理2018—2020美团面筋需要的自行领取
  5. W7移动硬盘分区合并
  6. c语言简单收银系统程序编码,我有个C语言编写的超市收银系统,请高手修改下,帮做流程图,可追加分...
  7. 揭秘《铃芽之旅》动画电影幕后特效制作细节
  8. win10和ubuntu18.04双系统解决罗技k380用一个频道无缝连接
  9. css权重机制,Css权重计算方式
  10. 【visum工作笔记】之三