Datatypes:Go 輕鬆支持數據庫 JSON 類型

GORM 是 Go 語言中最流行的 ORM 之一,它簡化了數據庫操作,提升了開發效率。然而,在某些情況下,標準的數據類型無法滿足複雜業務需求。

例如,**如何將 Go 中的結構體、切片、JSON 等類型映射到數據庫字段?**如何方便地進行序列化和反序列化?

爲了解決這些問題,GORM 提供了 datatypes (gorm.io/datatypes) 擴展庫,旨在簡化 Go 語言中複雜數據類型與數據庫字段之間的映射和操作。它提供了一系列預定義的數據類型,方便開發者直接使用,而無需自己編寫繁瑣的轉換代碼。

datatypes.JSON

datatypes.JSON 允許在數據庫中存儲 JSON 格式的數據。

定義字段類型 datatypes.JSON :

import "gorm.io/datatypes"

type User struct {
 ID   int
 Name string
 Conf datatypes.JSON // 對應數據庫JSON類型
}

func (u User) TableName() string {
 return "test_json_user"
}

插入 JSON 數據:

 user := User{
  Name: "Alice",
  Conf: datatypes.JSON(`{"theme": "dark", "lang": "en"}`),
 }
 db.Create(&user)
 // INSERT INTO `test_json_user` (`name`,`conf`) VALUES ('Alice',CAST('{"theme": "dark", "lang": "en"}' AS JSON))

檢查 JSON 鍵對應的值是否等於指定值:

查找 conf 字段中 theme 鍵的值是否爲 "dark"。

 var result User
 db.Where(datatypes.JSONQuery("conf").Equals("dark""theme")).Find(&result)
 // SELECT * FROM `test_json_user` WHERE JSON_EXTRACT(`conf`,'$.theme') = 'dark'

查詢 JSON 數據:

可以使用 json.Unmarshal 解析 JSON 結構。

type Conf struct {
 Theme string`json:"theme"`
 Lang  string`json:"lang"`
}

var result User
db.Where("name = ?""Alice").Find(&result)

var conf Conf
json.Unmarshal(result.Conf, &conf)
fmt.Printf("%+v\n", conf)
// {Theme:dark Lang:en}

datatypes.JSONType[T]

與使用 datatypes.JSON 需手動解析數據到結構體不同,使用 datatypes.JSONType[T],查詢時它可以自動將 JSON 數據映射到 Go 結構體。

定義字段類型 datatypes.JSONType[T] :

type User struct {
 ID   int
 Name string
 Conf datatypes.JSONType[Conf]// 對應數據庫JSON類型
}

type Conf struct {
 Theme string `json:"theme"`
 Lang  string `json:"lang"`
}

插入 JSON 數據:

 conf := Conf{Theme: "dark", Lang: "en"}

 user := User{
  Name: "Alice",
  Conf: datatypes.NewJSONType(conf),
 }
 db.Create(&user)

查詢 JSON 數據:

查詢時自動將 JSON 數據映射到 Go 結構體。使用 result.Conf.Data() 可以直接訪問 JSON 數據中的字段。

 var result User
 db.Where("name = ?""Alice").Find(&result)
 fmt.Printf("%+v\n", result.Conf.Data()) // {Theme:dark Lang:en}
 fmt.Println(result.Conf.Data().Theme)   // dark
 fmt.Println(result.Conf.Data().Lang)    // en

datatypes.JSONSlice[T]

datatypes.JSONSlice 可以方便地存儲 JSON 數組。查詢時自動解析 JSON 數組。

定義字段類型 datatypes.JSONSlice[T] :

type User struct {
 ID   int
 Name string
 Conf datatypes.JSONSlice[Conf] // 對應數據庫JSON類型
}

type Conf struct {
 Theme string `json:"theme"`
 Lang  string `json:"lang"`
}

插入 JSON 數據:

 conf := []Conf{
  {Theme: "dark", Lang: "en"},
  {Theme: "light", Lang: "zh"},
 }

 user := User{
  Name: "Alice",
  Conf: datatypes.NewJSONSlice(conf),
 }
 db.Create(&user)
 // INSERT INTO `test_json_user` (`name`,`conf`) VALUES ('Alice',CAST('[{"theme":"dark","lang":"en"},{"theme":"light","lang":"zh"}]' AS JSON))
    
/* 另一個例子儲存int數組
 type User struct {
  ID   int
  Name string
  Conf datatypes.JSONSlice[int] // 對應數據庫JSON類型
 }

 conf := []int{1, 2, 3, 4}

 user := User{
  Name: "Alice",
  Conf: datatypes.NewJSONSlice(conf),
 }
 db.Create(&user)*/

查詢 JSON 數據:

 var result User
 db.Where("name = ?""Alice").Find(&result)
 fmt.Printf("%+v\n", result.Conf)  // [{Theme:dark Lang:en} {Theme:light Lang:zh}]
 fmt.Println(result.Conf[0].Theme) // dark
 fmt.Println(result.Conf[0].Lang)  // en

通過這些示例,我們可以看到 gorm.io/datatypes 的強大之處:它簡化了複雜數據類型的處理,讓開發者可以更專注於業務邏輯。瞭解更多數據類型和使用方法請閱讀官方文檔。


References
https://github.com/go-gorm/datatypes

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/CpuMpv6-CKpjYH6jswnTFA