使用 gorm 库进行反映
Go reflect with gorm library
我在 golang 中使用 gorm 包 (https://github.com/jinzhu/gorm) 作为我的数据库库。我有很多 classes(数据库 tables),例如 "Hotel" 或 "Package"。复制代码不是好的编程习惯。作为一个愚蠢的例子 - 假设我想从每个 table 中获取第一个对象。我可以为每个对象编写此方法 (GetFirstHotel
、GetFirstPackage
...)。但更好的方法是只有一个方法 GetFirstItem
,我将使用第一个参数创建具有相同 class 作为参数的对象,然后将其传递给 gorm,gorm 将用数据库中的数据填充它, 然后 return 为 interface{}
。我试图为此使用反射,但失败了,因为我可能不太了解它。
也许我只是没有发现gorm库中的某些功能,或者我无法正确使用反射包。我应该如何实现 GetFirstItem
功能。是否可以实现这个,或者我应该重复我的代码?
package main
import (
"github.com/jinzhu/gorm"
)
var db gorm.DB
type Hotel struct {
ID int64
Name string
Lat float64
Lon float64
}
type Package struct {
ID int64
Name string
Text string
}
func GetFirstHotel() (hotel Hotel) {
db.First(&hotel)
}
func GetFirstPackage() (pack Package) {
db.First(&pack)
}
func main() {
var firstHotel, firstPackage interface{}
//first method
firstHotel = GetFirstHotel()
firstPackage = GetFirstPackage()
//method i want to use
firstHotel = GetFirstItem(Hotel{})
firstPackage = GetFirstItem(Package{})
}
func GetFirstItem(item interface{}) interface{} {
//how to implement this?
//probably with some use of reflect package
}
db.First 方法 returns 数据库引用并将行合并到传递的结构中。
最接近您所需的方法是
func GetFirstItem(item interface{}) error {
return db.First(item).Error
}
这只需要您保留对参数的引用
var firstHotel &Hotel{}
err := GetFirstItem(firstHotel)
返回所有类型的水化对象需要类型参数(泛型)。我想你会发现目前的情况是在一定范围内可行的。
另请参阅:Why no generics in Go?
我在 golang 中使用 gorm 包 (https://github.com/jinzhu/gorm) 作为我的数据库库。我有很多 classes(数据库 tables),例如 "Hotel" 或 "Package"。复制代码不是好的编程习惯。作为一个愚蠢的例子 - 假设我想从每个 table 中获取第一个对象。我可以为每个对象编写此方法 (GetFirstHotel
、GetFirstPackage
...)。但更好的方法是只有一个方法 GetFirstItem
,我将使用第一个参数创建具有相同 class 作为参数的对象,然后将其传递给 gorm,gorm 将用数据库中的数据填充它, 然后 return 为 interface{}
。我试图为此使用反射,但失败了,因为我可能不太了解它。
也许我只是没有发现gorm库中的某些功能,或者我无法正确使用反射包。我应该如何实现 GetFirstItem
功能。是否可以实现这个,或者我应该重复我的代码?
package main
import (
"github.com/jinzhu/gorm"
)
var db gorm.DB
type Hotel struct {
ID int64
Name string
Lat float64
Lon float64
}
type Package struct {
ID int64
Name string
Text string
}
func GetFirstHotel() (hotel Hotel) {
db.First(&hotel)
}
func GetFirstPackage() (pack Package) {
db.First(&pack)
}
func main() {
var firstHotel, firstPackage interface{}
//first method
firstHotel = GetFirstHotel()
firstPackage = GetFirstPackage()
//method i want to use
firstHotel = GetFirstItem(Hotel{})
firstPackage = GetFirstItem(Package{})
}
func GetFirstItem(item interface{}) interface{} {
//how to implement this?
//probably with some use of reflect package
}
db.First 方法 returns 数据库引用并将行合并到传递的结构中。
最接近您所需的方法是
func GetFirstItem(item interface{}) error {
return db.First(item).Error
}
这只需要您保留对参数的引用
var firstHotel &Hotel{}
err := GetFirstItem(firstHotel)
返回所有类型的水化对象需要类型参数(泛型)。我想你会发现目前的情况是在一定范围内可行的。
另请参阅:Why no generics in Go?