如何使用Gorm将MySQL的JSON列读取到自定义嵌入结构体中
GORM JSON列映射到自定义结构体实现方案
这里提供两种常用的实现方式,都可以直接将数据库JSON列的内容自动映射到你定义的[]Rule结构中:
方法1:GORM v2内置序列化器(无额外代码,最简单)
GORM v2原生支持字段序列化能力,只需要给对应字段加序列化标签即可,无需自定义接口实现:
import "gorm.io/gorm" type Permissions struct { // 其余字段定义 Rules []Rule `gorm:"type:json;serializer:json"` // type:json指定数据库列类型为json,serializer:json声明用JSON序列化器做自动转换 } type Rule struct { // Rule的字段需首字母大写(可导出),按需加json标签匹配数据库存储的key }
读写数据时GORM会自动完成JSON和[]Rule结构的互转,无需额外逻辑。
方法2:自定义类型实现标准接口(兼容所有GORM版本,灵活性高)
如果使用旧版本GORM,或者需要自定义序列化逻辑,可以把切片定义为独立类型,手动实现数据库驱动要求的两个接口:
import ( "database/sql/driver" "encoding/json" "errors" "fmt" ) // 定义自定义切片类型 type RuleList []Rule type Permissions struct { // 其余字段定义 Rules RuleList `gorm:"type:json"` } type Rule struct { // Rule的字段定义 } // Value 实现Valuer接口,写入数据库时自动调用,将结构体转为JSON字节 func (r RuleList) Value() (driver.Value, error) { return json.Marshal(r) } // Scan 实现Scanner接口,读取数据库时自动调用,将JSON字节解析为结构体 func (r *RuleList) Scan(value interface{}) error { bytes, ok := value.([]byte) if !ok { return errors.New(fmt.Sprint("JSON列类型不匹配,值为:", value)) } return json.Unmarshal(bytes, r) }
注意事项
- 数据库对应的列类型要设置为JSON/JSONB(MySQL用JSON,PostgreSQL用JSON/JSONB均可)
Rule结构体的字段必须首字母大写(可导出),否则JSON序列化时会自动忽略私有字段,导致映射为空- 如果需要严格校验JSON结构,可在Unmarshal时添加
DisallowUnknownFields配置,禁止JSON中出现结构体未定义的字段
内容的提问来源于stack exchange,提问作者user8606365
相关产品推荐
相关产品推荐

