在大多数场景下,进入一个页面后显示的是一个数据的列表,列表的数据量大小不一,数据量太大一次请求全部返回,会给前端非常大的压力,导致页面卡顿,所以需要分页来控制显示的条数,使得页面展示更加规整。就像看书一样,没有哪一本书是写在一页纸上的。
展示
下面这是一种常见的分页方式,一共有多少条数据,多少页,每页需要展示多少条数的数据,需要查看第几页,都是可以控制的,所以后端的同学需要将page的信息返回给前端。
计算
假如我们有一个学生表students
,我们要在界面以列表展示学生的信息。我们定义一个Page
的结构
1type Page struct {
2 PageNum int `json:"pageNum" form:"pageNum"` //页数
3 PageSize int `json:"pageSize" form:"pageSize"` //页面展示记录条数 默认是10
4 Total int `json:"total" form:"total"` //总页数
5 Offset int `json:"-"` //后端查询使用
6 PageSort
7}
8
9type PageSort struct {
10 SortName string `json:"sortName" form:"sortName"` //排序字段名
11 SortMethod string `json:"sortMethod" form:"sortMethod"` //排序方法 desc / asc
12}
13
14type PageInfo struct {
15 Page
16 List interface{} `json:"list"`
17}
前端同学需要给我们传递当前的页数pageNum和当前页展示的条数pageSize两个参数,还有排序的列和方法,后端处理好之后要将PageInfo
传递给前端,里面携带了当前page的信息。
当我们在查询列表数据之前,首先我们需要查询一个学生的总数,因为前端需要展示所有的数量,并且如果我们查的数量为0时,我们都不需要再去查列表数据了,避免浪费不必要的开销。
1func GetStudents(page Page) ([]Student, error) {
2 var count int64
3 db.Table("students").Count(&count)
4 //处理page
5 if count == 0 {
6 return nil, nil
7 }
8 //查询列表
9}
然后我们需要根据count计算列表查询需要的offset
1func Help(count int, page *Page) {
2 //如果当前页的条数小于0或者大于100,将当前页的条数设置为10,避免不合理请求
3 if page.PageSize <= 0 || page.PageSize > 100 {
4 page.PageSize = 10
5 }
6 //设置总数
7 page.Total = count
8 //根据每页的条数计算一共有多少页
9 pageNum := (count + page.PageSize - 1) / page.PageSize
10 //如果请求的页数比总页数还要大,将页数设置为最后一页,如果请求的页数为0,将页数设置为第一页
11 if page.PageNum > pageNum {
12 if 0 == pageNum {
13 page.PageNum = 1
14 } else {
15 page.PageNum = pageNum
16 }
17 }
18 //计算当前页之前所有页的条数,为offset
19 page.Offset = (page.PageNum - 1) * page.PageSize
20}
我们再用计算好的结果去查询列表数据
1func GetStudents(page Page) (*PageInfo, error) {
2 var count int64
3 db.Table("students").Count(&count)
4 //处理page
5 page.Help(&page)
6 if count == 0 {
7 return nil, nil
8 }
9 //查询列表
10 var students []Student
11 if err := db.Raw("select name, age from student order by ? limit ? offset ?", page.SortName+" "+page.SortMethod, page.PageSize, page.Offset).Scan(&students); err != nil {
12 return nil, err
13 }
14 return &PageInfo{
15 Page: page,
16 List: students,
17 }, nil
18}