前言
GORM作为一个go语言里知名的orm,可谓是文档详细,功能强大,操作简单,集所有的优势于一体,几乎可以说是没什么缺点。但是吧,作为一个刚从python转语言过来的新人,在Gin+GORM映射结构体这一环节可谓是踩坑不少。首先就是,我要接收一个数组,数据库字段类型为
varchar
,如果结构体类型定义为string
,则根本映射不到,如果是[]string
,则又会出现各种各样的错误,为此我也走了不少弯路。以此篇文章来记录一下。
自定义结构体
就先不说踩的坑了,先上解决办法,这其实也是一个坑,因为我没有认真看完文档,也没有联想起来解决办法,所以导致在此卡了很久。
我们无法通过[]string
或者[]map[string]interface{}
来进行入库。但是我们可以自定义结构,以此通过他的编译和入库,完成我们想要的功能。
type Front struct {
Banner []string `gorm:"type:varchar(255);not null" json:"banner" label:"Banner图"`
}
像上面这样,我们完全无法存储一个列表,即便存了,也是各种bug不断,此时就需要我们自定义类型。根据文档得知,我们要实现Value
和Scan
方法。
type Node struct {
List List `json:"list" `
}
type List []string
func (p List) Value() (driver.Value, error) {
return json.Marshal(p)
}
func (p *List ) Scan(data interface{}) error {
return json.Unmarshal(data.([]byte), &p)
}
// 将其修改为List类型。
type Front struct {
Banner List `gorm:"type:varchar(255);not null" json:"banner" label:"Banner图"`
}
这样,我们就实现了我们想要的功能,接收["1","2","3","4"]
这样的数据来存储到数据库了。
同样的,想列表嵌套数组的深层嵌套结构也可以通过自定义结构来完成。
type Hash struct {
Name string `json:"name"`
Link string `json:"link"`
}
type HashValue []Hash
func (p HashValue) Value() (driver.Value, error) {
return json.Marshal(p)
}
func (p *HashValue ) Scan(data interface{}) error {
return json.Unmarshal(data.([]byte), &p)
}
坑
再来说说我踩过的坑,虽然没成功,但是呢,我觉得有教育意义,本来一开始定义的结构体类型为string,然后无法接收到数组数据,随后我又将其改为了空接口。虽然能够接收到数据了,但是,依旧无法入库。
然后最重要的地方来了,我的思想出现了问题,既然我无法存入空接口数组数据,那我干脆存成字符串吧,于是我使用fmt.Sprintf
来将数据格式化为字符串,于是后边就针对字符串进行了各种操作,最终结果也是以失败告终。
此路不通之后,我就想着让字符串原封不动的入库,于是又将接收的结构体换成了map,通过这个终于成功的入库了,但是,问题又来了,既然是字符串,在进行序列化之后,前端会将字符串的符号进行自动的转义,针对转义问题我又进行了各种操作,从替换字符,到分割数组,卡在这里好几天。。。
总之呢,就是,只要思想不滑坡,办法总比困难多。希望大家能以此为戒。思想不要出现问题。
- Post link: https://www.godhearing.cn/gorm-zi-ding-yi-jie-gou/
- Copyright Notice: All articles in this blog are licensed under unless otherwise stated.