Serializer is an extensible interface that allows to customize how to serialize and deserialize data with database.
GORM предоставляет несколько сериализаторов по умолчанию: json, gob, unixtime, вот краткий пример того, как их использовать.
type User struct { Name []byte`gorm:"serializer:json"` Roles Roles `gorm:"serializer:json"` Contracts map[string]interface{} `gorm:"serializer:json"` JobInfo Job `gorm:"type:bytes;serializer:gob"` CreatedTime int64`gorm:"serializer:unixtime;type:time"`// сохранить int как datetime в базе данных }
type Roles []string
type Job struct { Title string Location string IsIntern bool }
После регистрации сериализатора вы можете использовать его с тегом serializer, например:
type User struct { Name []byte`gorm:"serializer:json"` }
Настраиваемый тип сериализатора
Вы можете использовать зарегистрированный сериализатор с тегами, вам также разрешено создавать настраиваемую структуру, которая реализует вышеуказанный SerializerInterface и напрямую использовать его в качестве типа поля, например:
type EncryptedString string
// ctx: содержит значения, относящиеся к области запроса // field: поле, использующее сериализатор, содержит настройки GORM, теги структуры // dst: текущее значение модели, `user` в приведенном ниже примере // dbValue: текущее значение поля в базе данных 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"))) casestring: *es = EncryptedString(strings.TrimPrefix(value, "hello")) default: return fmt.Errorf("unsupported data %#v", dbValue) } returnnil }
// ctx: содержит значения, относящиеся к области запроса // field: поле, использующее сериализатор, содержит настройки GORM, теги структуры // dst: текущее значение модели, `user` в приведенном ниже примере // fieldValue: текущее значение поля dst 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 { gorm.Model Password EncryptedString }
data := User{ Password: EncryptedString("pass"), }
DB.Create(&data) // INSERT INTO `serializer_structs` (`password`) VALUES ("hellopass")
var result User DB.First(&result, "id = ?", data.ID) // result => User{ // Password: EncryptedString("pass"), // }
DB.Where(User{Password: EncryptedString("pass")}).Take(&result) // SELECT * FROM `users` WHERE `users`.`password` = "hellopass"