前言
gorm
中表字段
使用自定义数据类型转换到json
在官网文档也有 本帖记录一下
官网写法
type JSON json.RawMessage
// 实现 sql.Scanner 接口,Scan 将 value 扫描至 Jsonb
func (j *JSON) Scan(value interface{}) error {
bytes, ok := value.([]byte)
if !ok {
return errors.New(fmt.Sprint("Failed to unmarshal JSONB value:", value))
}
result := json.RawMessage{}
err := json.Unmarshal(bytes, &result)
*j = JSON(result)
return err
}
// 实现 driver.Valuer 接口,Value 返回 json value
func (j JSON) Value() (driver.Value, error) {
if len(j) == 0 {
return nil, nil
}
return json.RawMessage(j).MarshalJSON()
}
自己写法1
写法跟官网东西都一样
type Cdkey struct{
addMail AddMail // 后面格式省略
}
type AddMail struct{
Id int
Name int
// 其他字段省略
}
// 读取值时返回json字符串
func (m AddMail) Value() (driver.Value, error) {
b, err := json.Marshal(m)
return string(b), err
}
// 扫描时转换为自定义数据类型
func (m *AddMail) Scan(v interface{}) error {
//>> text 转json
return json.Unmarshal(v.([]byte), &m)
}
注意第二种情况
type Cdkey struct{
addMail []AddMail // 后面格式省略
}
type AddMail struct{
Id int
Name int
// 其他字段省略
}
//当为数组情况时按照上一个步骤的方法是调用不到scan的
//需要将[]AddMail 重新声明一个类型
type AddMailList []AddMail
//修改Cdkey
type Cdkey struct{
addMail AddMailList // 后面格式省略
}
//scan方法修改为
func (m *AddMailList) Scan(v interface{}) error {
return json.Unmarshal(v.([]byte), &m)
}
感谢神秘赖总的帮助
调用cdkey.Create时会调用Value 获取数据值
另外一个方法
func (m AddMail) GormValue(ctx context.Context, db *gorm.DB) clause.Expr {
b, _ := json.Marshal(m)
return clause.Expr{
SQL:"'"+string(b)+"'",// 注意此处他是原样返回的 需要自己加引号
}
}