前言
最近项目中从Java转到Go,项目数据库使用的是MongoDB,在go项目中操作MongoDB发现一些的一些问题,在这里和大家分享一下。
空值问题
在java中,我们用DO和数据库集合中的Document进行映射,保存的时候如果字段是空的,那么保存的Document对应的字段是不存在的,这样看起来简洁并且可以节省数据库的存储空间。
但是用Go来实现的时候,定义相同的DO,发现数据库中保存了所有的字段,都是空的,如下所示:
问题原因:出现这个问题是因为java和go的不同类型的默认值是不一样的,针对string类型,go的默认值是一个空字符串而不是null,所以保存的时候也是空字符串。
解决办法:在DO的字段对应的tag上增加omitempty标识符,omitempty
是一个标签(tag)选项,用于指示 JSON 编码时,如果字段的值是零值(zero value),则忽略该字段而不进行编码。这样可以在 JSON 数据中省略那些默认零值的字段,使其更加紧凑。
主键问题
主键问题是遇到的第二个问题,之前java里面是直接定义一个id字段,类型为String,保存的时候mongodb会自动在数据库中生成_id字段的值,查询的时候_id的字段值也会自动赋值到id字段。但是转到go之后,发现这个字段没办法生成,我最开始在在json里面定义一个_id的tag。
结果发现必须自己手动赋值,我们知道_id字段是有索引的,如果手动赋值并且是随机的,那每次对更新数据对索引的操作很大,所以不合适,最终查阅资料费发现有ObjectId的实现,mongodb的主键字段就是ObjectId.。
Go里面有个primitive.ObjectID类型,这个就是标识的主键
但是这样定义的话,ID字段还是需要自己赋值的,只不过可以使用mongodb的自动生成器来实现,比如创建对象的时候:
whiteRules := &models.WhiteRuleDO{
//生成mongodb主键
ID : primitive.NewObjectID()
}
我查找了很多方式,都没有办法自动生成,必须手动赋值,这里确实有点不友好