在开发 Web 应用时,分页查询 是非常常见的需求。比如文章列表、用户管理后台、商品展示页,都需要分页展示数据。
在 Go 语言中,我们可以结合 GORM + Gin 框架,快速实现分页查询接口。本文将带你一步步实现一个 用户列表的分页接口。
一、环境准备
依赖库安装:
arduino
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
go get -u github.com/gin-gonic/gin
数据库使用 MySQL(也可换 SQLite、Postgres)。
二、定义用户模型
我们以 User
模型作为例子:
go
package main
import (
"github.com/gin-gonic/gin"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"log"
"net/http"
)
// User 用户模型
type User struct {
ID uint `gorm:"primaryKey"`
Name string `gorm:"size:100"`
Email string `gorm:"unique"`
Age int
}
var db *gorm.DB
func initDB() {
dsn := "root:123456@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"
var err error
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal("数据库连接失败:", err)
}
// 自动迁移
_ = db.AutoMigrate(&User{})
}
三、实现分页查询接口
分页查询的核心就是 计算 offset 和 limit:
- •
page
当前页(从 1 开始) - •
pageSize
每页数量 - •
offset = (page - 1) * pageSize
代码实现:
go
// 分页查询接口
func getUsers(c *gin.Context) {
// 获取查询参数,默认 page=1, pageSize=10
page := c.DefaultQuery("page", "1")
pageSize := c.DefaultQuery("pageSize", "10")
var (
users []User
total int64
)
// 转换为 int
var p, ps int
fmt.Sscanf(page, "%d", &p)
fmt.Sscanf(pageSize, "%d", &ps)
if p < 1 {
p = 1
}
if ps < 1 {
ps = 10
}
// 查询总数
db.Model(&User{}).Count(&total)
// 分页查询
db.Offset((p - 1) * ps).Limit(ps).Find(&users)
// 返回 JSON
c.JSON(http.StatusOK, gin.H{
"page": p,
"pageSize": ps,
"total": total,
"data": users,
})
}
在 main()
中注册路由:
scss
func main() {
initDB()
r := gin.Default()
r.GET("/users", getUsers)
r.Run(":8080")
}
四、接口调用效果
请求:
arduino
curl "http://localhost:8080/users?page=2&pageSize=5"
返回:
perl
{
"page": 2,
"pageSize": 5,
"total": 23,
"data": [
{"ID":6,"Name":"Alice","Email":"alice@test.com","Age":22},
{"ID":7,"Name":"Bob","Email":"bob@test.com","Age":25},
{"ID":8,"Name":"Tom","Email":"tom@test.com","Age":20},
{"ID":9,"Name":"Jerry","Email":"jerry@test.com","Age":30},
{"ID":10,"Name":"Lucy","Email":"lucy@test.com","Age":19}
]
}
五、总结与优化
✅ 本案例实现了一个 分页查询接口:
- • 支持动态
page
和pageSize
参数 - • 返回总数
total
,便于前端计算总页数 - • 返回当前页数据
🔧 优化点:
-
- 封装通用分页函数,避免每个接口都重复写分页逻辑。
-
- 加入排序功能 ,如
orderBy=age desc
。
- 加入排序功能 ,如
-
- 加入搜索过滤,例如按用户名查询。
这样,我们就能快速实现一个完整的 分页 + 搜索 + 排序 的列表接口。