前言
如果想把json存进数据库,array存入数据库,拿出来后也不想进行处理了,直接解析到结构体上直接用,数组,切片,json这些是非常规数据类型。这个时候我们就可以通过自定义来实现
官方文档:自定义数据类型
自定义的数据类型必须实现 Scanner 和 Valuer 接口,以便让 GORM 知道如何将该类型接收、保存到数据库
结构体转json存数据库
type Info struct { Name string Age int } type User struct { Id uint Info Info } //存入数据库 func (info Info) Value() (driver.Value, error) { str, err := json.Marshal(info) if err != nil { return nil, err } return string(str), nil } //从数据库取数据 func (info *Info) Scan(value interface{}) error { str, ok := value.([]byte) if !ok { return errors.New("不匹配的数据类型") } json.Unmarshal(str, info) return nil } func main() { db, _ := gorm.Open(mysql.New(mysql.Config{DSN: "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local"}), &gorm.Config{}) db.AutoMigrate(&User{}) db.Create(&User{Info: Info{Name: "wxf", Age: 20}}) var u User db.First(&u) fmt.Println(u) }
数组存数据库
type Info struct { Name string Age int } //存入数据库 func (info Info) Value() (driver.Value, error) { str, err := json.Marshal(info) if err != nil { return nil, err } return string(str), nil } //从数据库取数据 func (info *Info) Scan(value interface{}) error { str, ok := value.([]byte) if !ok { return errors.New("不匹配的数据类型") } json.Unmarshal(str, info) return nil } type User struct { Id uint Info Info //通过type定义数据库字段类型 Arr Arr `gorm:"type:varchar(191)"` } type Arr []string //存入数据库 func (arr Arr) Value() (driver.Value, error) { if len(arr) > 0 { str := arr[0] for _, v := range arr[1:] { str += "," + v } return str, nil } else { return "", nil } } //从数据库取数据 func (arr *Arr) Scan(value interface{}) error { str, ok := value.([]byte) if !ok { return errors.New("不匹配的数据类型") } *arr = strings.Split(string(str), ",") return nil } func main() { db, _ := gorm.Open(mysql.New(mysql.Config{DSN: "root:123456@tcp(127.0.0.1:3306)/gormDB?charset=utf8mb4&parseTime=True&loc=Local"}), &gorm.Config{}) db.AutoMigrate(&User{}) db.Create(&User{Info: Info{Name: "wxf", Age: 20}, Arr: Arr{"wxf", "haha", "666"}}) var u User db.First(&u) fmt.Println(u) }