您的位置:

GORM分页详解

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开发中的分页操作有所帮助。