整理一下自己以前寫的一個分頁功能代碼
代碼都是自己寫的,可能有不好的地方,望理解.
本文鏈接: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;