如何对列表分页

分页计算

Posted by jarvis on Thu, May 4, 2023

在大多数场景下,进入一个页面后显示的是一个数据的列表,列表的数据量大小不一,数据量太大一次请求全部返回,会给前端非常大的压力,导致页面卡顿,所以需要分页来控制显示的条数,使得页面展示更加规整。就像看书一样,没有哪一本书是写在一页纸上的。

展示

下面这是一种常见的分页方式,一共有多少条数据,多少页,每页需要展示多少条数的数据,需要查看第几页,都是可以控制的,所以后端的同学需要将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}