如何以一种好的方式在Golang中使用SQL NULL值和JSON?

Ale*_*lex 31 sql json go

Go类型喜欢Int64并且String不能存储空值,所以我发现我可以使用sql.NullInt64sql.NullString.

但是当我在Struct中使用它们,并使用json包从Struct生成JSON时,格式与我使用常规Int64String类型时的格式不同.

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`包也很方便.https://github.com/guregu/null我喜欢. (9认同)
  • 多棒的解决方案!谢谢! (4认同)
  • 也许说起来有些多余,但是让 Golang Playgrounds 展示这样的东西真是太棒了 - 真的对语言采用产生了巨大的影响。谢谢你的好回答。 (2认同)

Ste*_*ood 9

如果使用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网络服务器,则可以参考此要点

  • 这节省了很多时间。我以为我必须编写所有封送处理代码,但是此程序包可以完美运行。 (2认同)