我正在写一个页面,其中呈现了分页的Blog帖子列表。我在Go 1.12中使用GORM。 每个博客文章都有一个名为“用户”的作者,该用户可以在必要时包含一些其他员工信息。 (例如简介,函数标题等)
我的模特:
type EmployeeInfo struct {
UserID uint `gorm:"not null;unique"`
Title string `gorm:"not null"`
Intro string `gorm:""`
}
type User struct {
gorm.Model
Username string `gorm:"unique;not null"`
Password string `gorm:"unique;not null"`
FirstName string `gorm:"not null"`
LastName string `gorm:"not null"`
Company Company `gorm:"not null"`
Role string `gorm:"not null;default:user"`
}
type BlogPost struct {
gorm.Model
Title string `gorm:"not null"`
Slug string `gorm:"unique;not null;index"`
Intro string `gorm:"not null"`
Text string `gorm:"not null"`
Category string `gorm:"not null"`
PictureUrl string `gorm:"not null"`
Author User `gorm:"not null"`
AuthorID uint `gorm:"not null"`
}
我的当前代码如下:
func (hh *BlogIndexHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// set desired language
language.SetLanguage(r)
// set title
hh.data.Title = fmt.Sprintf(
"%s - %s",
language.Translate("blog", nil, false),
language.Translate("product", nil, false),
)
// get current page
hh.data.Page = 0
if intPage, err := strconv.Atoi(r.URL.Query().Get(pageQueryName)); err != nil && intPage >= 0 {
hh.data.Page = intPage
}
// get max page number
hh.data.MaxPage = 1
var totalPosts int
if err := hh.database.Model(&models.BlogPost{}).Count(&totalPosts).Error; err != nil {
totalPosts = 1
} else {
hh.data.MaxPage = roundUp(float64(totalPosts / PostsPerPage))
}
// if page > maxPage, set it right
if hh.data.Page > hh.data.MaxPage {
hh.data.Page = hh.data.MaxPage
}
// fetch blog posts
if err := hh.database.
Preload("Author").
Order("created_at DESC").
Offset(PostsPerPage * hh.data.Page).
Limit(PostsPerPage).
Find(&hh.data.Posts).
Error; err != nil {
log.Errorf(appengine.NewContext(r), "could not get posts: %v", err)
}
// set cacheable
system.SetCacheable(w, system.CacheTime1Day)
// send webpage
hh.template.Render("blog/index", w, hh.data)
}
但是,一个请求会触发3个不同的查询:
[2019-03-11 19:51:52] [29.55ms] SELECT count(*) FROM "blog_posts" WHERE "blog_posts"."deleted_at" IS NULL
[0 rows affected or returned ]
[2019-03-11 19:51:52] [27.50ms] SELECT * FROM "blog_posts" WHERE "blog_posts"."deleted_at" IS NULL ORDER BY created_at DESC LIMIT 9 OFFSET 0
[1 rows affected or returned ]
[2019-03-11 19:51:52] [49.86ms] SELECT * FROM "users" WHERE "users"."deleted_at" IS NULL AND (("id" IN ('58')))
是否可以将它们与GORM合并? 我想像手动查询一样对它们进行优化。
答案 0 :(得分:0)
GORM不支持JOIN
上的数据库级别Preload
。您有两种选择:
Preload
并接受以下事实:它执行了一个额外的查询以获取相关数据(除非您的服务器负担沉重,否则应该不会有问题)JOIN
编写自己的Raw Sql查询,并在一个查询中处理所有内容,然后将数据映射到结构。