GORM是一款流行的Go语言ORM库,它提供的分页功能十分强大,在web应用程序开发中被广泛使用。本文将从分页器、分页查询、分页插件、分页示例、以及获取分页总页数等多个方面详细阐述GORM的分页功能,并提供相关的代码示例。
一、GORM分页器
在进行GORM分页操作之前,我们需要先创建一个分页器。
type Paginator struct {
DB *gorm.DB
Total int64
Page int
Limit int
}
func New(db *gorm.DB, page, limit int) *Paginator {
return &Paginator{
DB: db,
Page: page,
Limit: limit,
}
}
分页器的结构体中包含了GORM的DB对象、总记录数、以及当前页码和每页显示的数量。同时,我们还创建了一个New函数来方便创建Paginator实例。
下面我们来看一个简单的分页查询的示例,记得在执行前先创建好相应的表,并向其中插入一些数据!
type User struct {
ID uint
Name string
Age uint
}
func main() {
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
db.AutoMigrate(&User{})
for i := 0; i < 20; i++ {
db.Create(&User{
Name: fmt.Sprintf("User%d", i),
Age: uint(i),
})
}
var users []User
paginator := New(db.Select("*").Where("age > ?", 5), 2, 5)
paginator.DB.Find(&users)
fmt.Println("Total:", paginator.Total)
fmt.Println("Page:", paginator.Page)
fmt.Println("Limit:", paginator.Limit)
fmt.Println("Users:", users)
}
我们在这里首先定义了一个User结构体,并使用AutoMigrate函数来创建相应的表,同时向其中插入了20条记录。在实际应用中,我们可以通过HTTP请求参数或其他方式获取相应的分页参数(如页码和每页显示数量),并传递给New函数创建分页器。
在这个例子中,我们选择第二页,每页5条记录进行查询,并将结果保存在users变量中。分页器查询时仅会返回正确的记录数据,并将查询结果中的总记录数保存到Paginator实例的Total属性中。使用fmt包来输出分页器的各项属性和查询到的数据。
二、GORM分页查询
除了使用Find函数进行普通查询以外,我们还可以使用Limit和Offset函数组合来进行分页查询。Limit函数用于限制查询返回的记录数,而Offset函数可用于跳过指定数量的结果。
下面展示了如何使用Limit和Offset实现分页查询:
paginator.DB.Limit(5).Offset(5).Find(&users)
这个例子将跳过前5条记录,并返回5条查询结果。
三、GORM分页插件
GORM提供了一些实用的分页插件,可以方便地在任何地方使用分页。
其中一个十分常用的插件是pagination。
// 安装插件
go get -u github.com/gobuffalo/packr/v2/packr2
go get -u github.com/biezhi/gorm-paginator/pagination
// 分页查询
func main() {
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
db.AutoMigrate(&User{})
for i := 0; i < 20; i++ {
db.Create(&User{
Name: fmt.Sprintf("User%d", i),
Age: uint(i),
})
}
var users []User
paginator := pagination.Paging(&pagination.Param{
DB: db,
Page: 2,
Limit: 5,
ShowSQL: true,
}, &users)
fmt.Println("Total:", paginator.Total)
fmt.Println("Page:", paginator.Page)
fmt.Println("Limit:", paginator.Limit)
fmt.Println("Users:", users)
}
pagination插件支持链式查询,其中Param结构体用于接收分页参数。需要注意的是,pagination插件会覆盖原始的分页查询参数,如果你有其他查询参数需要添加,需要手动添加到Param结构体中的query字段中。
四、GORM分页示例
下面给出一个完整的使用GORM进行分页的示例代码:
func main() {
// 连接数据库
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
db.AutoMigrate(&User{})
// 添加20个测试用户
for i := 0; i < 20; i++ {
db.Create(&User{
Name: fmt.Sprintf("User%d", i),
Age: uint(i),
})
}
// 创建分页器
page := 2
limit := 5
paginator := New(db.Select("*").Where("age > ?", 5), page, limit)
// 链式查询
paginator.DB.Order("age desc").Limit(limit).Offset(paginator.Offset()).Find(&users)
fmt.Printf("Total:%d, Page:%d, Limit:%d \n", paginator.Total, paginator.Page, paginator.Limit)
for i, user := range users {
fmt.Println(i, user.Name, user.Age)
}
}
在这个例子中,我们首先连接数据库,创建了用户表,并添加了20个测试用户。接着,我们定义了分页器的页码和每页记录数,并用New函数创建了Paginator实例。然后,我们在这个Paginator对象上进行分页查询,并将查询结果保存到users切片中。之后,我们输出查询结果和分页器的各项属性。
五、获取GORM分页总页数
经常会有这样的需求,即获取分页操作之后的总页数。我们直接来看GORM是如何实现的。
func (p *Paginator) TotalPages() int {
if p.Total == 0 {
return 0
}
if p.Limit == 0 {
return 0
}
pages := p.Total / int64(p.Limit)
if p.Total%int64(p.Limit) > 0 {
pages++
}
return int(pages)
}
在这个函数中,我们首先判断总记录数或分页大小是否为0,如果是0,则说明没有数据或查询参数不正确,返回0。否则,我们计算总页数并将其返回。
结语
本文详细阐述了GORM的分页功能,包括分页器、分页查询、分页插件、分页示例及获取分页总页数等多个方面,并提供了相关实用的代码示例。希望对大家在GORM开发中的分页操作有所帮助。