前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >protobuf 与 redis 的结合

protobuf 与 redis 的结合

作者头像
看、未来
发布2021-12-20 19:50:44
1.6K0
发布2021-12-20 19:50:44
举报

这是一个很不错的想法。

于是我去验证了一下。

然后我如愿以偿的失败了。

接着我验证了前辈的代码。

学习一下前辈代码中的框架,拿来在自己的业务中使用,八年前的代码,还是比较全面的。

msg.proto

使用的是 PB2,我比较海纳百川,那就用PB2吧(其实就是懒,不想改代码)

代码语言:javascript
复制
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呢,一会儿编译起来比较简单。

代码语言:javascript
复制
/* 
 * 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;
}

使用的时候呢,先把那个插入数据的代码放出来,把数据插进去,再用后面读的去读(其实也可以一气呵成,我就直接放出来了)

主要是这个框架,自己剥一下拿去用吧。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-12-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • msg.proto
  • test.cc
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档