golang mysql serializer

2022-12-29  本文已影响0人  哆啦在这A梦在哪

官方文档:https://gorm.io/docs/serializer.html

其实就两种:
1.官方提供的 几种写好的类型给你直接序列化
2.定义自己的类型,再自定义该类型序列化的逻辑

下面就是列子,看看就好,和官方一样的,就是加了一点自己的注解


// 自定义序列化逻辑类型
type EncryptedString string

// 给序列化的时候加上一个前缀
// 可以用在时间格式化上
// 不同的格式的数据处理都能使用,可以和逻辑分开不耦合
func (es *EncryptedString) Scan(ctx context.Context, field *schema.Field, dst reflect.Value, dbValue interface{}) (err error) {
    switch value := dbValue.(type) {
    case []byte:
        *es = EncryptedString(bytes.TrimPrefix(value, []byte("hello")))
    case string:
        *es = EncryptedString(strings.TrimPrefix(value, "hello"))
    default:
        return fmt.Errorf("unsupported data %#v", dbValue)
    }
    return nil
}

// 反序列化,就是取数据的时候加上点逻辑
// 要是有什么必要的默认处理逻辑都可以加
func (es EncryptedString) Value(ctx context.Context, field *schema.Field, dst reflect.Value, fieldValue interface{}) (interface{}, error) {
    return "hello" + string(es), nil
}

正式代码调用

type User struct {
    ID          int
    Title       EncryptedString // 直接使用这个类型即可
    Name        []byte                 `gorm:"serializer:json"`
    Roles       Roles                  `gorm:"serializer:json"`
    Contracts   map[string]interface{} `gorm:"serializer:json"` // json 和 varchar 类型都可以
    JobInfo     Job                    `gorm:"type:bytes;serializer:gob"`
    CreatedTime int64                  `gorm:"serializer:unixtime;type:time"` // store int as datetime into database
    // 注意这个时间格式,如果数据库是time 的能插入,但是sacan读取会出错,因为日期丢失了
    // 但是如果插入日期,读取没问题
    // 对应的应该是完整的 datetime
}

func (User) TableName() string {
    return "user"
}

type Roles []string

type Job struct {
    Title    string
    Location string
    IsIntern bool
}

func main() {
    DB, err := OpenMysqlClient("root:12345678@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local")
    if err != nil {
        log.Println(err)
        return
    }
    createdAt := time.Date(2020, 8, 1, 0, 8, 12, 12, time.UTC)
    log.Println("createdAt:", createdAt)
    log.Println("createdAt unix:", createdAt.Unix())
    data := User{
        Title:       "shitingbao",
        Name:        []byte("jinzhu"),
        Roles:       []string{"admin", "owner"},
        Contracts:   map[string]interface{}{"name": "jinzhu", "age": 10},
        CreatedTime: createdAt.Unix(),
        JobInfo: Job{
            Title:    "Developer",
            Location: "NY",
            IsIntern: false,
        },
    }

    if err := DB.Create(&data).Error; err != nil {
        log.Println("Create:", err)
        return
    }
    // INSERT INTO `users` (`name`,`roles`,`contracts`,`job_info`,`created_time`) VALUES
    //   ("\"amluemh1\"","[\"admin\",\"owner\"]","{\"age\":10,\"name\":\"jinzhu\"}",<gob binary>,"2020-01-01 00:08:00")

    var result User
    if err := DB.First(&result, "id = ?", data.ID).Error; err != nil {
        log.Println("First:", err)
        return
    }
    log.Println("result:", result)
}

func OpenMysqlClient(source string) (*gorm.DB, error) {
    d, err := gorm.Open(mysql.Open(source), &gorm.Config{})
    if err != nil {
        return nil, err
    }
    db, err := d.DB()
    if err != nil {
        return nil, err
    }
    db.SetMaxIdleConns(10)
    db.SetMaxOpenConns(30)
    return d, nil
}
上一篇下一篇

猜你喜欢

热点阅读