网站分页功能(获取页面数据/分页按钮信息)

整理一下自己以前写的一个分页功能代码

代码都是自己写的,可能有不好的地方,望理解.

本文链接:https://www.cnblogs.com/yang37/p/12806215.html

一、分页功能如何实现

    /*
    SELECT *  FROM questions  LIMIT 1,5; 
    获取1之后的5个数据(即2.3.4.5.6),即LIMIT 起始数,条数;   
           
            1页 起始数:0,   5
            2页 起始数:5,   5
            3页 起始数:10,  5
            n页 (n-1)*size, 5
            故起始数为(n-1)*size
   */
   所以要获取到每页的内容,关键就是获取"起始数"和设置"条数".

每页条数可以直接设置,起始数需要计算.

大致步骤

  • 页面传入page.size,做好格式校验.
  • 根据  "起始数= (page-1)*size"  计算出起始数.
  • 由  SELECT * FROM table_name LIMIT x,y  获取到需要的数据

详细步骤

1.controller传过来page与size.
page为当前页数,size为每页的数据数目.

2.校验传入的page与size是否合法.
1)size校验

    //校验size
    //eg:传入前端得到的size 
    //合法返回原值,不合法返回默认值checkedSize=5
    public String checkSizeNow(String tempSize){
        String checkedSize = "5";

        //验证是否为数字格式
        String regex = "^[0-9]*$";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(tempSize);
        boolean isMatch = m.matches();
        if (!isMatch) {
            return checkedSize;
        }
        //即使满足 也要处理为0的情况
        if ("0".equals(tempSize)){
            return  checkedSize;
        }

        return tempSize;
    }

接收检查后的size:

 String checkedSize = pageProvider.checkSizeNow(size);

2)page校验
为什么要传入总条数和页码?
比如12条数据,5个/页.传入页数6合理吗?
不合理,是因为我们根据总条数12和每页数量5计算出了页数最大为3.

    //矫正当前页page
    //eg:传入前端得到的当前页tempNowPage,数据总条数,每一页数目size
    //合法返回当前页,不合法返回1.
    public String checkPageNow(String tempNowPage,String tempCounts,String tempSize){

        //不满足数字格式 页数返回1
        String regex = "^[0-9]*$";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(tempNowPage);
        boolean isMatch = m.matches();
        if (!isMatch) {
            return "1";
        }

        //为数字格式则做小于第一页和大于最后一页的处理
        Integer nowPage = Integer.parseInt(tempNowPage);
        Integer size = Integer.parseInt(tempSize);
        Integer counts = Integer.parseInt(tempCounts);

        Integer totalPage;

        //计算总页数
        if (counts % size == 0) {
            totalPage = counts / size;
        } else {
            totalPage = (counts / size) + 1;
        }

        //规定当前页的范围
        if (nowPage <= 0) {
            nowPage = 1;
        }

        if (nowPage > totalPage) {
            nowPage = totalPage;
        }

        return nowPage.toString();
    }

接收检查后的page:

String checkedPage = pageProvider.checkPageNow(page, tatalCount, checkedSize);

在校验page的时候我们就发现还需要总条数和每页数量size,size前面已经做了校验,那总条数呢?
总条数是我们从数据库查询出来的,不会让用户传递过来,所以不用做格式校验,直接计算就可以了.

3.根据传入的page与size计算起始数

    //根据页码和大小计算起始数
    public String gainStartNum(String page, String size) {
        Integer tempNum = (Integer.parseInt(page) - 1) * Integer.parseInt(size);
        if (tempNum <= 0){
            tempNum = 0;
        }
        String startNum = tempNum.toString();
        return startNum;
    }

接收计算出的起始数:

String startNum = pageProvider.gainStartNum(checkedPage, checkedSize);

4.根据获取到的数据为PageDTO赋值
在获取到起始数后,结合每页数目,就可以查询出来对应页面应包含的数据.
这些数据可以直接封装后返回.
但是页面下方的分页按钮部分如何处理?
分页按钮部分,包含着当前页数,是否有上一页,是否有下一页等等.
例如下面这样:

可以将数据信息分页信息封装,返回前端,例如.

@Data
public class IndexQuestionAndPageDTO {
    List<IndexQuestionDTO> indexQuestionDTOList;
    private PageDTO pageDTO;
}

计算所需要的PageDTO
PageDTO参考代码:

package com.yang.demo.dto;
import lombok.Data;
import java.util.Set;

/**
 * @Author Yiang37
 * @Date 2020/3/13 21:35
 * Description:
 * 分页
 */
@Data
public class PageDTO {
    private boolean hasFirst = true;
    private boolean hasEnd = true;
    private boolean hasPrevious = true;
    private boolean hasNext = true;
    private Set<Integer> pageNumbers;

    private Integer nowPage;
    private Integer endPage;
}

计算PageDTO

    //根据传入的page和size计算pageDTO
    //当前页、每页条数、总数、范围(左/右显示几个)
    public PageDTO gainPageDTO(String tempNowPage, String tempSize, String tempCounts, Integer range) {
        // << < 1 2 3 4 5 6 7 > >>
        PageDTO pageDTO = new PageDTO();

        Integer nowPage = Integer.parseInt(tempNowPage);
        Integer size = Integer.parseInt(tempSize);
        Integer counts = Integer.parseInt(tempCounts);

        Integer totalPage;
        Set<Integer> whatPages = new TreeSet<>();

        // eg:13条 每页五个

        //矫正size 错误设置为默认的5 正则
        String regex = "^[0-9]*$";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(size.toString());
        boolean isMatch = m.matches();
        if (!isMatch) {
            size = 5;
        }

        //1.计算总页数
        if (counts % size == 0) {
            totalPage = counts / size;
        } else {
            totalPage = (counts / size) + 1;
        }

        //2.规定当前页和大小的范围 因为计算total要size 所以size先矫正
        if (nowPage <= 0) {
            nowPage = 1;
        }
        if (nowPage > totalPage) {
            nowPage = totalPage;
        }


        //3.根据当前页 判断包含哪些页
        Integer sizeRight = totalPage - nowPage;
        Integer sizeLeft = nowPage - 1;

        //对左边的处理
        if (nowPage != 1){
            if (sizeLeft >= range) {
                //最多只显示左边的range个
                for (int i = 1; i <= range; i++) {
                    whatPages.add(nowPage - i);
                }
            } else {
                //显示sizeLeft个
                for (int i = 1; i <= sizeLeft; i++) {
                    whatPages.add(nowPage - i);
                }
            }
        }

        //对右边的处理
        if (!nowPage.equals(totalPage)){
            if (sizeRight >= range) {
                for (int j = 1; j <= range; j++) {
                    whatPages.add(nowPage + j);
                }
            } else {
                for (int j = 1; j <= sizeRight; j++) {
                    whatPages.add(nowPage + j);
                }
            }
        }
        whatPages.add(nowPage);

        //4.上页下页 第一页最后一页的处理
        if (nowPage == 1) {
            pageDTO.setHasFirst(false);
            pageDTO.setHasPrevious(false);
        }
        if (nowPage.equals(totalPage)) {
            pageDTO.setHasEnd(false);
            pageDTO.setHasNext(false);
        }


        pageDTO.setPageNumbers(whatPages);
        pageDTO.setNowPage(nowPage);
        pageDTO.setEndPage(totalPage);
        return pageDTO;
    }

接收计算得到的PageDTO:

//获取页码数据 //也要矫正页码和大小
 PageDTO pageDTO = pageProvider.gainPageDTO(checkedPage, checkedSize, tatalCount, 3);

二、代码汇总

  • PageDTO类
package com.yang.demo.dto;
import lombok.Data;
import java.util.Set;

/**
 * @Author Yiang37
 * @Date 2020/3/13 21:35
 * Description:
 * 分页DTO类
 */
@Data
public class PageDTO {
    private boolean hasFirst = true;
    private boolean hasEnd = true;
    private boolean hasPrevious = true;
    private boolean hasNext = true;
    private Set<Integer> pageNumbers;

    private Integer nowPage;
    private Integer endPage;
}
  • PageProvider类
package com.yang.demo.provider;

import com.yang.demo.dto.PageDTO;
import org.springframework.stereotype.Component;

import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author Yiang37
 * @Date 2020/3/13 16:23
 * Description:
 * 分页工具类
 */

@Component
public class PageProvider {


    /*
    SELECT *  FROM questions  LIMIT 1,5;   显示1之后的5个
            1 0,5
            2 5,5
            3 10,5
            n (n-1)*size 5
            故起始数为(n-1)*size
   */
    //根据页码和大小计算起始数
    public String startNum(String page, String size) {
        Integer tempNum = (Integer.parseInt(page) - 1) * Integer.parseInt(size);
        if (tempNum <= 0){
            tempNum = 0;
        }
        String startNum = tempNum.toString();
        return startNum;
    }

    /*
     * 现在是第一页 不显示首页 上一页 ...
     * 计算好PageDTO 中的五个值
     *
     * 当前页码
     * size
     * 总条数
     * */
    //根据传入的page和size计算pageDTO
    //当前页、每页条数、总数、范围
    public PageDTO gainPageDTO(String tempNowPage, String tempSize, String tempCounts, Integer range) {
        // << < 1 2 3 4 5 6 7 > >>
        PageDTO pageDTO = new PageDTO();

        Integer nowPage = Integer.parseInt(tempNowPage);
        Integer size = Integer.parseInt(tempSize);
        Integer counts = Integer.parseInt(tempCounts);

        Integer totalPage;
        Set<Integer> whatPages = new TreeSet<>();

        // eg:13条 每页五个

        //矫正size 错误设置为默认的5 正则
        String regex = "^[0-9]*$";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(size.toString());
        boolean isMatch = m.matches();
        if (!isMatch) {
            size = 5;
        }

        //1.计算总页数
        if (counts % size == 0) {
            totalPage = counts / size;
        } else {
            totalPage = (counts / size) + 1;
        }

        //2.规定当前页和大小的范围 因为计算total要size 所以size先矫正
        if (nowPage <= 0) {
            nowPage = 1;
        }
        if (nowPage > totalPage) {
            nowPage = totalPage;
        }


        //3.根据当前页 判断包含哪些页
        Integer sizeRight = totalPage - nowPage;
        Integer sizeLeft = nowPage - 1;

        //对左边的处理
        if (nowPage != 1){
            if (sizeLeft >= range) {
                //最多只显示左边的range个
                for (int i = 1; i <= range; i++) {
                    whatPages.add(nowPage - i);
                }
            } else {
                //显示sizeLeft个
                for (int i = 1; i <= sizeLeft; i++) {
                    whatPages.add(nowPage - i);
                }
            }
        }

        //对右边的处理
        if (!nowPage.equals(totalPage)){
            if (sizeRight >= range) {
                for (int j = 1; j <= range; j++) {
                    whatPages.add(nowPage + j);
                }
            } else {
                for (int j = 1; j <= sizeRight; j++) {
                    whatPages.add(nowPage + j);
                }
            }
        }
        whatPages.add(nowPage);

        //4.上页下页 第一页最后一页的处理
        if (nowPage == 1) {
            pageDTO.setHasFirst(false);
            pageDTO.setHasPrevious(false);
        }
        if (nowPage.equals(totalPage)) {
            pageDTO.setHasEnd(false);
            pageDTO.setHasNext(false);
        }


        pageDTO.setPageNumbers(whatPages);
        pageDTO.setNowPage(nowPage);
        pageDTO.setEndPage(totalPage);
        return pageDTO;
    }


    //矫正大小
    public String checkSizeNow(String tempSize){
        String checkedSize = "5";

        //验证是否为数字格式
        String regex = "^[0-9]*$";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(tempSize);
        boolean isMatch = m.matches();
        if (!isMatch) {
            return checkedSize;
        }
        //即使满足 也要处理为0的情况
        if ("0".equals(tempSize)){
            return  checkedSize;
        }

        return tempSize;
    }

    //矫正页码数
    public String checkPageNow(String tempNowPage,String tempCounts,String tempSize){

        //不满足数字格式 页数返回1
        String regex = "^[0-9]*$";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(tempNowPage);
        boolean isMatch = m.matches();
        if (!isMatch) {
            return "1";
        }

        //为数字格式则做小于第一页和大于最后一页的处理
        Integer nowPage = Integer.parseInt(tempNowPage);
        Integer size = Integer.parseInt(tempSize);
        Integer counts = Integer.parseInt(tempCounts);

        Integer totalPage;

        //计算总页数
        if (counts % size == 0) {
            totalPage = counts / size;
        } else {
            totalPage = (counts / size) + 1;
        }

        //规定当前页的范围
        if (nowPage <= 0) {
            nowPage = 1;
        }

        if (nowPage > totalPage) {
            nowPage = totalPage;
        }

        return nowPage.toString();
    }

}

三、使用步骤

1.获取数据总条数count.例如

tatalCount = questionMapper.findQuestionTotalCount();

2.校验size,page,计算startNum,例如

String checkedSize = pageProvider.checkSizeNow(size);
String checkedPage = pageProvider.checkPageNow(page, tatalCount, checkedSize);
String startNum = pageProvider.startNum(checkedPage, checkedSize);  

3.根据startNum获取数据,例如

dbQuestionList = questionMapper.findQuestionQueryList(startNum, checkedSize);

获取到的数据库数据按要求进行转换,此处转成了indexQuestionDTOList.

4.获取分页DTO,例如

PageDTO pageDTO = pageProvider.gainPageDTO(checkedPage, checkedSize, tatalCount, 3);

5.返回所需的数据,例如

        ...
  //设置页面对象
        IndexQuestionAndPageDTO indexQuestionAndPageDTO = new IndexQuestionAndPageDTO();
        indexQuestionAndPageDTO.setIndexQuestionDTOList(indexQuestionDTOList);
        indexQuestionAndPageDTO.setPageDTO(pageDTO);

        return indexQuestionAndPageDTO;
原文地址:https://www.cnblogs.com/yang37/p/12806215.html