protobuf 与 redis 的结合
【摘要】 这是一个很不错的想法。于是我去验证了一下。然后我如愿以偿的失败了。接着我验证了前辈的代码。学习一下前辈代码中的框架,拿来在自己的业务中使用,八年前的代码,还是比较全面的。 msg.proto使用的是 PB2,我比较海纳百川,那就用PB2吧(其实就是懒,不想改代码)package cn.vicky.model.seri; message User { required int32 id ...
这是一个很不错的想法。
于是我去验证了一下。
然后我如愿以偿的失败了。
接着我验证了前辈的代码。
学习一下前辈代码中的框架,拿来在自己的业务中使用,八年前的代码,还是比较全面的。
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;
}
使用的时候呢,先把那个插入数据的代码放出来,把数据插进去,再用后面读的去读(其实也可以一气呵成,我就直接放出来了)
主要是这个框架,自己剥一下拿去用吧。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)