golang Gorm 对MySQL Json 的迁移查询操作

此操作是在MySQL Version == 8.0 下产生的 参考自掘金,可能年代久远,已经不能用了

Gorm 让可以让人自定义类型 根据规则 实现 Valuer, Scanner 这两个接口(一个序列化数据, 一个反序列化数据) 将数据存入带数据库

看了下 gorm.Model 的源码它自带的DeletedAt 就是这样实现出来的

栗子:

package main

import (
    "database/sql/driver"
    "encoding/json"
    "fmt"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

var db *gorm.DB

func init() {
    var err error
    dns := "root:123@tcp(127.0.0.1:3306)/blog?charset=utf8&parseTime=True&loc=Local&timeout=10s"
    db, err = gorm.Open(mysql.Open(dns), &gorm.Config{})
    if err != nil {
        panic(err)
    }
}

// User 用户
type User struct {
    gorm.Model
    Name string 
    Profile Profile `gorm:"type:json;comment:'个人信息'"json:"profile"`
}

// Profile 个人信息
type Profile struct {
    Email string `json:"email"`
    PhoneNo string `json:"phoneNo"`
}

// Value 实现方法
func (p Profile) Value() (driver.Value, error) {
    return json.Marshal(p)
}

// Scan 实现方法
func (p *Profile) Scan(input interface{}) error {
    return json.Unmarshal(input.([]byte), p)
}


func main()  {
    db.AutoMigrate(&User{})
    u := User{
        Name: "maocat",
        Profile: Profile{
            Email: "maocatzk@gmail.com",
            PhoneNo: "18888888888",
        },
    }
    db.Save(&u)

    u.Profile.PhoneNo = "13666666666"
    db.Save(&u)

    var u1 User
    db.
        Where("profile->'$.email' = (?)", "maocatzk@gmail.com").
        First(&u1)
    fmt.Println(u1.Name)
    fmt.Println(u1.Profile)
}

当然如果要存入数组形式的数据只需要下一步就能解决

type Profile []int

最后, MySQL还是最好不要弄json玩,感觉有点背离了它关系数据库的原则