在本文中,我们解决了在 Go 中使用 SQL NULL 值的困境以及如何处理它们有效的 JSON 表示。
使用 Go 类型(例如 int64 和 string)时,不能直接存储 null 值。但是,我们可以使用 sql.NullInt64 和 sql.NullString 来实现此目的。然而,当这些类型嵌入到结构体中并使用 json 包转换为 JSON 时,生成的格式与使用常规 int64 和 string 类型时获得的格式不同。
出现这种差异是因为 JSON 表示sql.Null*** 类型包括一个附加级别,因为这些类型本质上是结构本身。因此,需要一种解决方法来实现所需的 JSON 格式。
与其放弃在 SQL 数据库中使用 NULL 值,一个可行的解决方案是创建一个实现 json 的自定义类型。 Marshaller 和 json.Unmarshaler 接口。通过嵌入 sql.NullInt64 类型,我们保留了 SQL 方法,同时获得了对 JSON 处理的控制。以下是演示此方法的示例:
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,JSON 表示形式与所需的格式一致。
要演示此解决方案,您可以在 Go Playground 中运行以下代码:
func main() { type Person struct { Age int64 `json:"age"` AgeJson JsonNullInt64 `json:"ageJson"` } p := Person{ Age: 10, AgeJson: sql.NullInt64{Int64: 0, Valid: true}, } b, _ := json.Marshal(p) fmt.Println(string(b)) }
输出将类似于以下:
{"age":10,"ageJson":10}
这种方法允许无缝处理 SQL 和 JSON 中的 NULL 值,保持数据表示的一致性。
以上是如何在 Go 中高效处理 SQL NULL 值及其 JSON 表示?的详细内容。更多信息请关注PHP中文网其他相关文章!