首页 > 解决方案 > 如何使用 Gorm 进行预加载

问题描述

我遇到了预加载和关联的障碍

type Entity struct {
  ID           uint `gorm:"primary_key"`
  Username     string
  Repositories []*Repository `gorm:"many2many:entity_repositories"`
}

type Repository struct {
  ID       uint `gorm:"primary_key"`
  Name     string
  Entities []*Entity `gorm:"many2many:entity_repositories"`
} 

对于小用户数,使用以下预加载就可以了

 db.Preload("Repositories").Find(&list)

也试过

 db.Model(&User{}).Related(&Repository{}, "Repositories").Find(&list)

预加载似乎是 aselect * entities然后使用 a 进行内部连接SELECT * FROM "repositories" INNER JOIN "entity_repositories" ON "entity_repositories"."repository_id" = "repositories"."id" WHERE ("entity_repositories"."entity_id" IN ('1','2','3','4','5','6','7','8','9','10'))

随着用户数量的增加,这不再是可维护的,因为它达到了 sqlite 限制(开发)。我已经尝试了许多排列!..实际上我想我只是想让它做类似的事情

SELECT entities.*, repositories.*  
FROM entities 
JOIN entity_repositories ON entity_repositories.entity_id = entities.id
JOIN repositories ON repositories.id = entity_repositories.repository_id
ORDER BY entities.id

并为我填写模型..

我是在做明显错误的事情还是?

标签: databasegogo-gormpreloading

解决方案


不幸的是,这正是 GORM 处理预加载的方式。

go-pg的查询稍好一些,但没有 GORM 相同的功能。在某些情况下,它仍然会执行多个查询。

老实说,我建议只使用原始 SQL构建查询,特别是如果您知道您的模型在编译时会是什么样子。我最终在我的项目中采用了这种方法,尽管我不知道我的模型会是什么样子。


推荐阅读