在关系型数据库的设计中,有时候会由于性能优化或处理方便等各种原因,有将一些非基本类型的对象存入数据库的场景,在每次读取和写入时手动转换实在麻烦,下面,就介绍下如何利用golang的sql.Scanner和sql.Valuer接口实现自动转换。
直接上代码
type StringSlice []string
func (t StringSlice) Value() (driver.Value, error) {
return json.Marshal(t)
}
func (t *StringSlice) Scan(input interface{}) error {
switch input.(type) {
case []byte:
inputByte := input.([]byte)
if len(inputByte) == 0 {
inputByte = []byte("null")
}
return json.Unmarshal(inputByte, t)
case string:
s := input.(string)
if s == "" {
s = "null"
}
return json.Unmarshal([]byte(s), t)
default:
return fmt.Errorf("Unable to convert %v of %T to %T", input, input, t)
}
}
上面的代码是如何将字符串切片转成json格式存入,需要注意的是这边虽然Value方法将值转为[]byte类型存入数据库的,但是由于数据库引擎的版本、操作系统等原因,Scan函数中input对象可能是[]byte类型也可能是string类型,需要做类型判断特殊处理
另外,如果使用了orm处理的话,比如gorm,需要手动在指定该对象的存入数据库的类型,如
type TT struct {
Ips StringSlice `gorm:"type:text"`
}
以上,将TT对象存入数据库和将对象从数据库读出时,就能自动将Ips字段自动转换为指定结构了