Serializer is an extensible interface that allows to customize how to serialize and deserialize data with database.
GORM provides some default serializers: json, gob, unixtime, here is a quick example of how to use it.
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"`// store int as datetime into database }
type Roles []string
type Job struct { Title string Location string IsIntern bool }
After registering a serializer, you can use it with the serializer tag, for example:
type User struct { Name []byte`gorm:"serializer:json"` }
Customized Serializer Type
You can use a registered serializer with tags, you are also allowed to create a customized struct that implements the above SerializerInterface and use it as a field type directly, for example:
type EncryptedString string
// ctx: contains request-scoped values // field: the field using the serializer, contains GORM settings, struct tags // dst: current model value, `user` in the below example // dbValue: current field's value in database 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: contains request-scoped values // field: the field using the serializer, contains GORM settings, struct tags // dst: current model value, `user` in the below example // fieldValue: current field's value of the 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"