为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
阿波罗的战车 2021-11-15 15:57:56
走类型,如Int64并String不能存储空值,所以我发现我可以用sql.NullInt64和sql.NullString这一点。但是当我在 Struct 中使用这些,并使用json包从 Struct 生成 JSON 时,格式与我使用常规Int64和String类型时的格式不同。JSON 有一个额外的级别,因为 sql.Null*** 也是一个 Struct。对此是否有好的解决方法,或者我不应该在我的 SQL 数据库中使用 NULL?
查看完整描述

2 回答

?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

诸如此类的类型sql.NullInt64不为 JSON 编组或解组实现任何特殊处理,因此适用默认规则。由于该类型是一个结构体,它被编组为一个对象,其字段作为属性。


解决此问题的一种方法是创建您自己的实现json.Marshaller/json.Unmarshaler接口的类型。通过嵌入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

}

如果您使用此类型代替sql.NullInt64,则应按预期对其进行编码。


你可以在这里测试这个例子:http : //play.golang.org/p/zFESxLcd-c


查看完整回答
反对 回复 2021-11-15
?
慕侠2389804

TA贡献1719条经验 获得超6个赞

如果您使用null.v3包,则不需要实现任何 marshal 或 unmarshal 方法。它是 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

}

如果您想查看使用 sqlite、nulls 和 json 的完整 Golang 网络服务器,您可以查阅此要点。


查看完整回答
反对 回复 2021-11-15
  • 2 回答
  • 0 关注
  • 258 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信