golang 解决 protobuf 因为 XXX 插入数据库报错的情况

hwholiday · · 945 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

## 起因 + 在一个老项目里面直接用的 protobuf 生成的结构体与数据库交互 + 在 protoc 2 生成的 protobuf 没有 XXX 这些东西生成故能正常运行 + 因为版本升级到 protoc 3 后编译的 protobuf 就不能正常运行了,会出现数据库找不到 XXX_ 这些字段的情况 ## 解决方案 + 把每张表单独生成 struct 放在 models 层里面,这样的话老服务改动太大我肯定是不能接受的 + 因为我们使用的 orm ,在xorm 中如果 struct 某个字段不需要映射的话就可以用 xorm:"-" + gorm 也可以这样操作 gorm:"-" + 那我们就可以在 XXX_ 这些字段后面的 tag 中添加忽略,就可以实现我们的目表 ## 开始搞事情 #### 获取代码 ``` go get github.com/golang/protobuf/protoc-gen-go ``` #### 修改代码 + 在路径 github.com/golang/protobuf/protoc-gen-go/generator/generator.go 下找到 generateInternalStructFields 方法 + 在XXX_ 后添加 xorm:\"-\" or gorm:\"-\" ``` // generateInternalStructFields just adds the XXX_<something> fields to the message struct. func (g *Generator) generateInternalStructFields(mc *msgCtx, topLevelFields []topLevelField) { g.P("XXX_NoUnkeyedLiteral\tstruct{} `json:\"-\" xorm:\"-\"`") // prevent unkeyed struct literals if len(mc.message.ExtensionRange) > 0 { messageset := "" if opts := mc.message.Options; opts != nil && opts.GetMessageSetWireFormat() { messageset = "protobuf_messageset:\"1\" " } g.P(g.Pkg["proto"], ".XXX_InternalExtensions `", messageset, "json:\"-\" xorm:\"-\"`") } g.P("XXX_unrecognized\t[]byte `json:\"-\" xorm:\"-\"`") g.P("XXX_sizecache\tint32 `json:\"-\" xorm:\"-\"`") } ``` #### 编译代码得到 protoc-gen-go 并放到 /go/bin/ 下 + 编译 proto ``` protoc --go_out=. *.proto ``` ## 成果 ``` type BoolValue struct { Value bool `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-" xorm:"-"` XXX_unrecognized []byte `json:"-" xorm:"-"` XXX_sizecache int32 `json:"-" xorm:"-"` } ``` ## 结语 + 通过这样的方法我们就可以实现我们想要的样子了 + 不过还是建议一个表对应一个 struct 放在 models 里面 + 欢迎添加QQ一起讨论 ## 联系 QQ: 3355168235

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

945 次点击  ∙  1 赞  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传