Go类型喜欢Int64并且String不能存储空值,所以我发现我可以使用sql.NullInt64和sql.NullString.
但是当我在Struct中使用它们,并使用json包从Struct生成JSON时,格式与我使用常规Int64和String类型时的格式不同.
JSON有一个额外的级别,因为sql.Null***也是一个Struct.
有没有一个很好的解决方法,或者我不应该在我的SQL数据库中使用NULL?
Jam*_*dge 49
类似的类型sql.NullInt64不实现JSON编组或解组的任何特殊处理,因此默认规则适用.由于类型是结构,因此它将作为对象进行编组,并将其字段作为属性.
解决此问题的一种方法是创建自己的类型来实现json.Marshaller/ json.Unmarshalerinterfaces.通过嵌入sql.NullInt64类型,我们可以免费获得SQL方法.像这样的东西:
type JsonNullInt64 struct {
sql.NullInt64
}
func (v JsonNullInt64) MarshalJSON() ([]byte, error) {
if v.Valid {
return json.Marshal(v.Int64)
} else {
return json.Marshal(nil)
}
}
func (v *JsonNullInt64) UnmarshalJSON(data []byte) error {
// Unmarshalling into a pointer will let us detect null
var x *int64
if err := json.Unmarshal(data, &x); err != nil {
return err
}
if x != nil {
v.Valid = true
v.Int64 = *x
} else {
v.Valid = false
}
return nil
}
Run Code Online (Sandbox Code Playgroud)
如果您使用此类型代替sql.NullInt64,则应按预期编码.
您可以在此处测试此示例:http://play.golang.org/p/zFESxLcd-c
如果使用null.v3包,则无需实现任何编组或解组方法。它是sql.Null结构的超集,可能正是您想要的。
package main
import "gopkg.in/guregu/null.v3"
type Person struct {
Name string `json:"id"`
Age int `json:"age"`
NickName null.String `json:"nickname"` // Optional
}
Run Code Online (Sandbox Code Playgroud)
如果您想查看使用sqlite,null和json的完整Golang网络服务器,则可以参考此要点。