protobuf 与 redis 的结合

举报
看,未来 发表于 2021/12/30 00:35:04 2021/12/30
【摘要】 这是一个很不错的想法。于是我去验证了一下。然后我如愿以偿的失败了。接着我验证了前辈的代码。学习一下前辈代码中的框架,拿来在自己的业务中使用,八年前的代码,还是比较全面的。 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

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。