protobuf 与 redis 的结合
Posted 看,未来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了protobuf 与 redis 的结合相关的知识,希望对你有一定的参考价值。
这是一个很不错的想法。
于是我去验证了一下。
然后我如愿以偿的失败了。
接着我验证了前辈的代码。
学习一下前辈代码中的框架,拿来在自己的业务中使用,八年前的代码,还是比较全面的。
msg.proto
使用的是 PB2,我比较海纳百川,那就用PB2吧(其实就是懒,不想改代码)
package cn.vicky.model.seri;
message User
required int32 id = 1; // 主键,唯一
required string username = 2; // 帐号
required string password = 3; // 密码
optional string email = 4; // 邮箱(可选)
repeated Person person = 5; // 账户拥有的角色(可以重复)
message Person
required int32 id = 1; // 主键,唯一
required string name = 2; // 角色名字
repeated PhoneNumber phone = 3; // 电话号码(可以重复)
// 枚举类型
enum PhoneType
MOBILE = 0;
HOME = 1;
WORK = 2;
message PhoneNumber
required string number = 1;
optional PhoneType type = 2 [default = HOME];
test.cc
为啥用个cc呢,一会儿编译起来比较简单。
/*
* File: main.cpp
* Author: Vicky.H
* Email: eclipser@163.com
*/
#include <iostream>
#include <fstream>
#include "model.pb.h"
#include "hiredis.h"
int main(void)
// 创建User对象
cn::vicky::model::seri::User u;
u.set_id(1);
u.set_username("Jack");
u.set_password("123456");
u.set_email("289997171@qq.com");
// 创建User中的一个角色
cn::vicky::model::seri::Person* _person1 = u.add_person();
_person1->set_id(1);
_person1->set_name("P1");
// 创建角色中的一个电话号码:1
cn::vicky::model::seri::PhoneNumber* _phone1 = _person1->add_phone();
_phone1->set_number("+8613618074943");
_phone1->set_type(cn::vicky::model::seri::MOBILE);
// 创建角色中的一个电话号码:2
cn::vicky::model::seri::PhoneNumber* _phone2 = _person1->add_phone();
_phone2->set_number("02882334717");
_phone2->set_type(cn::vicky::model::seri::WORK);
// 创建User中的一个角色
cn::vicky::model::seri::Person* _person2 = u.add_person();
_person2->set_id(2);
_person2->set_name("P2");
// 创建角色中的一个电话号码:1
cn::vicky::model::seri::PhoneNumber* _phone3 = _person2->add_phone();
_phone3->set_number("+8613996398667");
_phone3->set_type(cn::vicky::model::seri::MOBILE);
// 创建角色中的一个电话号码:2
cn::vicky::model::seri::PhoneNumber* _phone4 = _person2->add_phone();
_phone4->set_number("02882334717");
_phone4->set_type(cn::vicky::model::seri::WORK);
// 将对象以二进制保存
const int byteSize = u.ByteSize();
std::cout << "byteSize = " << byteSize << std::endl;
char buf[byteSize];
bzero(buf, byteSize);
u.SerializeToArray(buf, byteSize);
// 建立redis链接
redisContext *c;
redisReply *reply;
struct timeval timeout = 1, 500000; // 1.5 seconds
c = redisConnectWithTimeout((char*) "127.0.0.1", 3307, timeout);
if (c->err)
printf("Connection error: %s\\n", c->errstr);
exit(1);
// 第一次执行:将对象写入redis数据库
// reply = (redisReply*) redisCommand(c, "SET %b %b", u.username().c_str(), (int) u.username().length(), buf, byteSize); // 重点!!!
// printf("SET (binary API): %s\\n", reply->str);
// freeReplyObject(reply);
// 第二次执行:从redis数据库读取对象数据
reply = (redisReply*) redisCommand(c, "Get Jack");
std::cout << "reply->len = " << reply->len << "\\nreply->str : \\n" << reply->str << std::endl; // 这里打印不完
std::cout << "---------------------------" << std::endl;
cn::vicky::model::seri::User u2;
u2.ParseFromArray(reply->str, reply->len);
std::cout << u2.id() << std::endl;
std::cout << u2.username() << std::endl;
std::cout << u2.password() << std::endl;
std::cout << u2.email() << std::endl;
std::cout << "---------------------------" << std::endl;
for (int i = 0; i < u2.person_size(); i++)
cn::vicky::model::seri::Person* p = u2.mutable_person(i);
std::cout << p->id() << std::endl;
std::cout << p->name() << std::endl;
for (int j = 0; j < p->phone_size(); j++)
cn::vicky::model::seri::PhoneNumber* phone = p->mutable_phone(j);
std::cout << phone->number() << std::endl;
std::cout << "---------------------------" << std::endl;
return 0;
使用的时候呢,先把那个插入数据的代码放出来,把数据插进去,再用后面读的去读(其实也可以一气呵成,我就直接放出来了)
主要是这个框架,自己剥一下拿去用吧。
以上是关于protobuf 与 redis 的结合的主要内容,如果未能解决你的问题,请参考以下文章