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...

相关推荐
雪隐30 分钟前
用Flutter做背单词APP-03为了给单词库塞满数据,我让AI给我打了上万份工
前端·人工智能·后端
苏三说技术1 小时前
为什么越来越多的人使用PostgreSQL?
后端
Csvn1 小时前
📊 SQL 入门 Day 1:SELECT & WHERE — 数据查询的基本功
后端·sql
不一样的少年_1 小时前
不用框架,手搓 AI Agent:(一) 先让它跑起来
前端·后端·agent
用户526835677901 小时前
《拒绝当背锅侠!写了个 WebHook 中间件,让局域网硬件在服务挂掉时“喊”出来》
后端
云技纵横1 小时前
线上报 Deadlock,怎么从日志里找出是哪两条 SQL 打架?
后端
卷无止境1 小时前
Python数据进阶专题:用声明式验证让数据管道告别"惊喜"
后端·python·数据分析
glartchen1 小时前
win11下使用 WSL2 部署kali 虚拟机(不踩坑版)
后端
聂二AI落地内参1 小时前
ComfyUI 平台化:能力契约、节点白名单和积分预扣怎么串起来
后端
用户7827110810632 小时前
Spring MVC RESTful 员工管理实战 ——踩坑全记录
后端