Gorm分页新方案,你学会了吗?

开发 前端
虽然Gorm的文档中介绍了如何使用Scopes来实现分页,但在灵活性和可用性上仍有改进空间。本文介绍了一种利用Gorm的Clauses特性来简化分页并扩展其功能的优雅替代方案。

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中实现强大且可重用的分页功能。

责任编辑:武晓燕 来源: 源自开发者
相关推荐

2024-09-26 14:27:14

2023-01-26 00:28:45

前端测试技术

2023-06-05 08:29:46

HTMLWebViewJavaScript

2023-08-01 12:51:18

WebGPT机器学习模型

2024-01-02 12:05:26

Java并发编程

2023-01-10 08:43:15

定义DDD架构

2024-02-04 00:00:00

Effect数据组件

2024-01-19 08:25:38

死锁Java通信

2023-07-26 13:11:21

ChatGPT平台工具

2022-06-16 07:50:35

数据结构链表

2023-01-31 08:02:18

2023-10-06 14:49:21

SentinelHystrixtimeout

2023-05-05 06:54:07

MySQL数据查询

2024-03-06 08:28:16

设计模式Java

2023-08-26 21:34:28

Spring源码自定义

2023-03-26 22:31:29

2022-07-13 08:16:49

RocketMQRPC日志

2024-02-02 11:03:11

React数据Ref

2022-12-06 07:53:33

MySQL索引B+树

2023-06-26 13:08:52

GraphQL服务数据
点赞
收藏

51CTO技术栈公众号