如何优雅的使用 GORM 进行分页?

GORM 是 Go 中使用最广泛的 ORM 包,但尽管如此,它缺少一些“基本”功能。其中一个缺失的功能就是分页(Pagination)。

分页是管理应用程序中大型数据集的一个重要功能。它是一种限制和显示数据库中部分总数据的方法,这样就不需要一次性检索整个表,这样可以极大的提高接口性能,降低超时失败的概率。

虽然 GORM 提供了关于如何使用scopes 进行分页的文档,但在灵活性和可用性方面仍有改进的空间。在这里,我将介绍一种使用 GORM 的 Clauses 进行分页的替代方法。

使用 Scopes 的分页

GORM 的官网文档介绍了使用 Scopes 进行分页的代码示例:

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,这种方法与使用 scope 略有不同,因为 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 Clauses 函数中使用这个结构体:

clause.Expression
gorm.StatementModifier

所以结构看起来是这样的:

func (p *Pagination) ModifyStatement(stm *gorm.Statement) {
    // We modify statement to add the pagination
    db := stm.DB
    stm.DB.Limit(p.size).Offset((p.page - 1) * p.pageSize)
}

func (p *Pagination) Build(_ clause.Builder) {
    // The Build method is left empty since pagination does not require any additional SQL clauses.
}

之后,可以按照以下方式使用分页:

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

为了使这种方法可重用并增强其功能,这里介绍一个小众的包 PaGorminator:一个利用此功能进行分页的库,同时添加了其他功能,如无分页请求和自动填充元数据,如总页数和总计数。

使用方法如下:

// Add plugin
_ = db.Use(pagorminator.PaGormMinator{})
...
pageRequest, _ := pagorminator.PageRequest(0, 10)
db.Clauses(pageRequest).Find(&users)
// this will apply pagination, and also populate pageRequest with:
// - the total number of pages
// - total count

往期文章推荐

欢迎关注我:

  • 知识星球:云原生 AI 实战营,10+ 高质量体系课( Go、云原生、AI Infra)、15+ 实战项目,助你提高技术天花板,入大厂、拿高薪;
  • 微信GZH:令飞编程,分享 Go、云原生、AI Infra 相关技术。回复「资料」免费下载 Go、云原生、AI 等学习资料;
  • 哔哩哔哩:令飞编程 ,分享技术、职场、面经等,并有免费直播课「云原生AI高新就业课」,大厂级项目实战到大厂面试通关。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值