记录一下之前在 Stack Overflow
和 链滴社区 提过的一个问题。
问题是查询结果中包含了表中不存在的一个别名字段,如何将这个非表结构字段的查询结果通过 GORM 读取到表对应的模型结构体中?
DROP TABLE IF EXISTS "test"."test";
CREATE TABLE "test"."test" (
"id" varchar(32) NOT NULL,
"name" varchar(255) COLLATE "pg_catalog"."default",
"remark" varchar(255) COLLATE "pg_catalog"."default"
);
ALTER TABLE "test"."test" ADD CONSTRAINT "test_pkey" PRIMARY KEY ("id");
type Test struct {
ID string `gorm:"column:id;type:varchar(32);primaryKey;comment:唯一 ID,流水号" json:"id"` // 唯一 ID,流水号
Name string `gorm:"column:name;type:varchar(255);comment:名称" json:"name"` // 名称
Remark string `gorm:"column:remark;type:varchar(255);comment:备注" json:"remark"` // 备注
MoreInfo string `gorm:"-" json:"moreInfo"` // 更多信息,非表结构字段
}
test := Test{ID: "0000000001"}
gormDB.Select("*, 'testMoreInfoVal' AS more_Info").Where(&test).Find(&test)
好吧,当时刚入门 Go 开发一段时间,也是刚开始用 GORM 不久,现在回过来看看我这个问题提的确实是有点蠢了。
🗨 哇哦,转眼都 7 个月过去了,马上都要 2022 年了,真的又是瞎忙的一年呢。
有两种解决方案,回复原文是这样耐心告诉我的:
If the table structure is set and you aren't using AutoMigrate then this is solved by just changing your tags to make MoreInfo a read-only field and making sure you use the alias
more_info
to match the way GORM does DB -> Go naming translation.
type Test struct {
ID string `gorm:"column:id;type:varchar(32);primaryKey;comment:唯一 ID,流水号" json:"id"` // 唯一 ID,流水号
Name string `gorm:"column:name;type:varchar(255);comment:名称" json:"name"` // 名称
Remark string `gorm:"column:remark;type:varchar(255);comment:备注" json:"remark"` // 备注
MoreInfo string `gorm:"->" json:"moreInfo"` // 更多信息,非表结构字段
}
If you are using AutoMigration then the problem will be that a more_info column will be created in your table, though GORM will prevent writing to that column when using the struct.
What you could do in that case is use a new struct which embeds the Test struct like so:
type Test struct {
ID string `gorm:"column:id;type:varchar(32);primaryKey;comment:唯一 ID,流水号" json:"id"` // 唯一 ID,流水号
Name string `gorm:"column:name;type:varchar(255);comment:名称" json:"name"` // 名称
Remark string `gorm:"column:remark;type:varchar(255);comment:备注" json:"remark"` // 备注
MoreInfo string `gorm:"->" json:"moreInfo"` // 更多信息,非表结构字段
}
type TestExt struct {
Test
MoreInfo string `gorm:"->" json:"moreInfo"` // 更多信息
}
testext := TestExt{}
gormDB.Model(&Test{}).Select("*, 'testMoreInfoVal' AS more_info").
Where(Test{ID: "0000000001"}).Find(&testext)
等了几个小时,等待过程中去忙别的事了,也确实没想到解决方案,得到答案的时候很感动,真的特别感谢这位大佬的回复。
意思是说,如果没有使用 GORM 的自动迁移,可以把结构体中 MoreInfo
字段的 gorm
标签改成 ->
,告诉 GORM 这是一个只读字段,就能够把查询结果中的字段值读取到模型结构体中。
🗨 我当时真的是脑子抽筋了,为什么要把 gorm
标签设置成忽略这个字段呢 🤦。
如果这个模型结构体使用了 GORM 的自动迁移,那就再新加一个不自动迁移的扩展信息结构体就是了。
然后原结构体只保留表结构中存在的字段,将原结构体嵌入到扩展结构体,再将表结构中不存在的别名字段添加到扩展信息结构体中,gorm
标签还是设置成只读权限。
这样在使用 GORM 时,将 Model
设置成原结构体 &Test{}
,查询结果接收器设置为扩展信息结构体 &TestExt{}
,就可以完美解决啦,即不影响原结构体的自动迁移,也可以正常读取到别名字段的值。
如果有遇到同样问题的老伙计,这里推荐使用方案二,可以避免污染原模型结构体。
因为我确实不需要使用 GORM 的自动迁移,所以我当时选择了方案一,毕竟一行代码能解决的事情,就不要用 10 行代码去解决,多写多错,少写少错,是吧。🤣
另外,告诉你一个小秘密,在 Stack Overflow 提 Golang 的 GORM 问题时,不要把标签设置成 gorm
,要设置成 go-gorm
,不信你试试。
2021 年 12 月 25 日,看把我闲的,女朋友今天不在,我都开始炒冷饭了,还是一个人发布于 https://zixizixi.cn/golang-gorm-reads-value-of-the-alias-field
内容声明 | |
---|---|
标题: GORM 读取别名字段(非表结构字段)值的方法 | |
链接: https://zixizixi.cn/golang-gorm-reads-value-of-the-alias-field | 来源: iTanken |
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可,转载请保留此声明。
|