官方文档: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
}
网友评论