GORM 分頁新方案

Gorm 是 Go 語言中最常用的 ORM(對象關係映射)包之一,但它在某些功能上仍有不足,其中之一就是分頁。分頁是管理 Web 應用程序中大數據集的基本功能。通過分頁,可以限制和顯示數據庫中的部分數據,而不必一次性檢索整個表的數據。

雖然 Gorm 的文檔中介紹瞭如何使用 Scopes 來實現分頁,但在靈活性和可用性上仍有改進空間。本文介紹了一種利用 Gorm 的 Clauses 特性來簡化分頁並擴展其功能的優雅替代方案。

使用 Gorm 的 Scopes 進行分頁

Gorm 的文檔中將 Scopes 介紹爲重用常用代碼的方法。在文檔示例中,我們可以看到定義了一個類似於以下的分頁 Scope 函數:

func Paginate(page, pageSize int) func(db *gorm.DB) *gorm.DB {
  return func (db *gorm.DB) *gorm.DB {
    // validate page and pageSize
    ...
    offset := (page - 1) * pageSize
    return db.Offset(offset).Limit(pageSize)
  }
}

page := 0
pageSize := 10
db.Scopes(Paginate(page, pageSize)).Find(&users)

因此,爲了應用分頁,我們需要使用代碼db.Scopes(Paginate(page, pageSize))

使用 Clauses 進行分頁

另一種更爲優雅的方法是使用 Gorm 的 Clauses。這種方法與使用 Scopes 略有不同,因爲 Clauses 負責修改數據庫查詢,特別是 WHERE 子句。

首先定義分頁結構體:

type Pagination struct {
  page     int
  pageSize int
}

func (p *Pagination) GetPage() int { return p.page }
func (p *Pagination) GetPageSize() int { return p.pageSize }

然後,實現使用該結構體的 gorm 子句函數所需的兩個接口:

func (p *Pagination) ModifyStatement(stm *gorm.Statement) {
  // 修改語句以添加分頁
  db := stm.DB
  stm.DB.Limit(p.pageSize).Offset((p.page - 1) * p.pageSize)
}

func (p *Pagination) Build(_ clause.Builder) {
  // Build方法留空,因爲分頁不需要額外的SQL子句
}

之後,可以按如下方式使用分頁:

pagination := Pagination{
  page: 0,
  pageSize: 10,
}
db.Clauses(&pagination).Find(&users)

爲了使這種方法可重用並增強其功能,我開發了 Pagorminator——一個簡化 Gorm 分頁並添加高級功能的庫,例如未分頁請求和自動元數據填充(如總頁數和總計數)。使用方法如下:

// 添加插件
_ = db.Use(pagorminator.PaGormMinator{})

pageRequest, _ := pagorminator.PageRequest(0, 10)
db.Clauses(pageRequest).Find(&users)
// 這將應用分頁,並填充pageRequest,包括:
// - 總頁數
// - 總計數

分頁是數據庫驅動應用程序的關鍵功能。通過利用 Clauses 和類似 Pagorminator 的工具,可以在 Gorm 中實現強大且可重用的分頁功能。希望您能嘗試一下,並分享您的想法!

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/l63KmS-RqSAWZ98ry8Cl3Q