英文:
Gorm Find result to interface
问题
我正在尝试使用Gorm为我的API构建一个通用的CrudRepository结构体。我知道泛型将在Go语言的第二个版本中引入,但我尝试使用反射或其他库来构建这个库。
在我的CrudRepository中:
func (repository *BaseRepository) find(result interface{}, pageSize int, page int) error {
if page < 1 {
return errors.ExceedsMinimumInt("page", "", 0, true, nil)
}
offset := (page - 1) * pageSize
ent := reflect.Zero(reflect.TypeOf(result))
repository.db = repository.db.Limit(pageSize).Offset(offset)
err := repository.db.Find(&ent).Error
result = ent
if err != nil {
return err
}
return nil
}
并且像这样调用这个方法:
func List(){
var entityList []MyEntity
find(entityList, 1, 10)
}
我认为,我不能将任何接口引用传递给**Gorm.db.Find()**方法。是否有其他方法可以成功实现?
英文:
I am trying to build a generic CrudRepository struct using Gorm for my api.
I know generics are coming to GoLang in version 2 but I try to build this lib using reflection or any other lib.
In my CrudRepository:
func (repository *BaseRepository) find(result interface{}, pageSize int, page int) error {
if page < 1 {
return errors.ExceedsMinimumInt("page", "", 0, true, nil)
}
offset := (page - 1) * pageSize
ent := reflect.Zero(reflect.TypeOf(result))
repository.db = repository.db.Limit(pageSize).Offset(offset)
err := repository.db.Find(&ent).Error
result = ent
if err != nil {
return err
}
return nil
}
And calling this method sth like:
func List(){
var entityList []MyEntity
find(entityList, 1, 10)
}
I think, I cannot pass any interface reference into Gorm.db.Find() method
Is there any other way to succeed?
答案1
得分: 1
使用切片的指针作为自定义 find
方法的输入参数。
func (repository *BaseRepository) find(result interface{}, pageSize int, page int) error {
if page < 1 {
return errors.ExceedsMinimumInt("page", "", 0, true, nil)
}
if reflect.TypeOf(result).Kind() != reflect.Slice { // 检查 ❗️
return errors.New("`result` 不是一个切片")
}
offset := (page - 1) * pageSize
db = db.Limit(pageSize).Offset(offset)
if err := db.Find(result).Error; err != nil {
return err
}
return nil
}
用法 👇🏻
var entityList []MyEntity
err := find(&entityList, 10, 1)
此外,你还需要检查输入参数(result
),因为 db.Find
不适用于查找单个结构体 👇🏻(检索单个对象)
如果你想避免 ErrRecordNotFound 错误,可以使用类似
db.Limit(1).Find(&user)
的方式,Find 方法既接受结构体数据,也接受切片数据。
例如(Book
表为空):
b := Book{}
rowsAffectedQuantity := db.Find(&b).RowsAffected // 0
err = db.Find(&b).Error // nil
英文:
Use a pointer of a slice as input argument of custom find
method.
func (repository *BaseRepository) find(result interface{}, pageSize int, page int) error {
if page < 1 {
return errors.ExceedsMinimumInt("page", "", 0, true, nil)
}
if reflect.TypeOf(result).Kind() != reflect.Slice { 👈 check ❗️
return errors.New("`result` is not a slice")
}
offset := (page - 1) * pageSize
db = db.Limit(pageSize).Offset(offset)
if err := db.Find(result).Error; err != nil {
return err
}
return nil
}
usage 👇🏻
var entityList []MyEntity
err := find(&entityList, 10, 1)
Also you have to check input argument (result
), because db.Find
isn't fit to find single strut 👇🏻 (Retrieving a single object)
> If you want to avoid the ErrRecordNotFound error, you could use Find
> like db.Limit(1).Find(&user), the Find method accepts both struct and
> slice data
For example (Book
table is empty):
b := Book{}
rowsAffectedQuantity := db.Find(&b).RowsAffected // 👈 0
err = db.Find(&b).Error // 👈 nil
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论