Datatypes:Go 轻松支持数据库JSON类型

GORM 是 Go 语言中最流行的 ORM 之一,它简化了数据库操作,提升了开发效率。然而,在某些情况下,标准的数据类型无法满足复杂业务需求。

例如,**如何将 Go 中的结构体、切片、JSON 等类型映射到数据库字段?**如何方便地进行序列化和反序列化?

为了解决这些问题,GORM 提供了 datatypes (gorm.io/datatypes) 扩展库,旨在简化 Go 语言中复杂数据类型与数据库字段之间的映射和操作。它提供了一系列预定义的数据类型,方便开发者直接使用,而无需自己编写繁琐的转换代码。

datatypes.JSON

datatypes.JSON 允许在数据库中存储 JSON 格式的数据。

定义字段类型 datatypes.JSON :

go 复制代码
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 数据:

go 复制代码
	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"。

go 复制代码
	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 结构。

go 复制代码
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.JSONTypeT

与使用 datatypes.JSON 需手动解析数据到结构体不同,使用 datatypes.JSONTypeT,查询时它可以自动将 JSON 数据映射到 Go 结构体。

定义字段类型 datatypes.JSONTypeT

go 复制代码
type User struct {
	ID   int
	Name string
	Conf datatypes.JSONType[Conf]// 对应数据库JSON类型
}

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

插入 JSON 数据:

go 复制代码
	conf := Conf{Theme: "dark", Lang: "en"}

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

查询 JSON 数据:

查询时自动将 JSON 数据映射到 Go 结构体。使用 result.Conf.Data() 可以直接访问 JSON 数据中的字段。

go 复制代码
	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.JSONSliceT

datatypes.JSONSlice 可以方便地存储 JSON 数组。查询时自动解析 JSON 数组。

定义字段类型 datatypes.JSONSliceT

go 复制代码
type User struct {
	ID   int
	Name string
	Conf datatypes.JSONSlice[Conf] // 对应数据库JSON类型
}

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

插入 JSON 数据:

go 复制代码
	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 数据:

go 复制代码
	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

github.com/go-gorm/dat...

相关推荐
choumou_M13 分钟前
MySQL_1:数据库悲观锁
后端·spring·spring cloud
Lost of 程序猿40 分钟前
ASP.NET Core SignalR 实战:从实时推送到底层协议与高可用部署
后端·asp.net
JasmineWr1 小时前
Spring BeanDefinition 与 Bean 生命周期、循环依赖解析
java·后端·spring
QQ_21696290961 小时前
【项目编号:project86564】SpringBoot供应链管理系统:采购、供应商、库存、销售、统计报表一体化实战
java·spring boot·后端
灯澜忆梦1 小时前
【基于GO的Web开发10】gin获取HTML-Form表单提交参数
前端·后端·golang·html·gin
SomeB1oody10 小时前
【RustyML入门】6.3. 并行归约
开发语言·后端·机器学习·rust·教程
Profile排查笔记10 小时前
指纹浏览器哪个好?从 Profile、代理、权限和自动化能力判断是否适合
前端·人工智能·后端·自动化
用户9385156350711 小时前
用 AI 结对编程从 0 搭一个"单词后台管理系统":Next.js + Supabase + Drizzle + shadcn/ui 全记录
后端·postgresql·next.js
爱学习的小邓同学11 小时前
Golang --- (1)第一个Golang程序
开发语言·后端·golang