go - 如何合并查询
问题描述
我正在编写一个页面,其中呈现博客文章列表,并带有分页。我在 Go 1.12 中使用 GORM。每篇博文都有一个名为 User 的作者,如果需要,该用户可以包含一些额外的员工信息。(例如介绍,功能标题,...)
我的模型:
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 合并?我想优化这些,就像手动查询一样。
解决方案
GORM 不JOIN
支持Preload
. 你有两个选择:
- 要么使用
Preload
并接受它执行额外查询以获取相关数据的事实(除非您的服务器负载很重,否则这应该不是问题) - 或者您可以编写自己的Raw Sql查询,
JOIN
并在一个查询中处理所有内容,然后将数据映射到结构。
推荐阅读
- python - 在硒中。如何使用 Span 类单击第二个索引/列表?
- python - 火炬张量添加维度
- mysql - 仅当值与多个其他值的 100% 匹配时才获取数据 SQL
- python - 如何在 Python 中使用 Speech_recognition 获取单词时间戳?
- google-cloud-platform - 无法按日期表从 BigQuery 导出分区到 GCP
- imu - IMU 的位置和速度
- python - 未找到带有参数“(”,)“的“客户”的反向操作。尝试了 1 种模式:['customer/(?P
[^/]+)/$'] - react-native - 具有相同宽度的标题和行的 react-native-table-component 列,其中数据可以具有动态长度
- python - 如何使用 python 禁止字符更改序列化程序字段名称
- python - 将 Sagemaker 清单注释转换为 Pascal VOC XML/CSV