之前我用Gorm存入一些非基本类型的数据到数据库的一个字段,都是将这个字段的类型选择json.RawMessage,手动将变量序列化为Json,然后再存入数据库,从数据库里面拿出这个字段时还要手动反序列化。这样做,存入的时候可以存入任何类型的字段,假如我是确定的非基本类型字段,能不能简单一点

今天,我问了一下ChatGPT还有什么办法

显然还有更好的办法,为结构体实现Scanner和Valuer方法
比如,我这边有一个字段需要往数据库里面存入字符串列表,但是MySql是不直接支持存入列表的,所以选择数据库类型为Json

不能把类型直接写为 []string,因为它没有实现Scanner和Valuer方法,不能序列化和反序列化,存入和读取的时候会报错
这里我们自己为[]string定义一个类型别名,并且给它实现上面两个方法
// Platforms 平台列表
type Platforms []string
// Value
// @Description 实现 driver.Valuer(写入数据库)
// @Author Ham 2025-06-01 10:09:33
// @Return driver.Value JSON编码的字节流
// @Return error 错误
func (v Platforms) Value() (driver.Value, error) {
return json.Marshal(v)
}
// Scan
// @Description 实现 sql.Scanner(从数据库读取并反序列化)
// @Author Ham 2025-06-01 10:20:00
// @Param value interface{} 数据库传入的值
// @Return error 错误
func (v *Platforms) Scan(value interface{}) error {
bytes, ok := value.([]byte)
if !ok {
return fmt.Errorf("无法将数据库值转换为字节切片 []byte")
}
return json.Unmarshal(bytes, v)
}
要注意,最后这个字段用的是什么类型就给这个类型实现这两个方法就可以了,如果不是自己定义的类型,可以为那个类型创建一个别名
正文完