如果讓你來設計一個分頁功能, 你會怎麼設計? 前後端如何互動?
阿新 • • 發佈:2021-06-18
一、是什麼
在我們做資料查詢的時候,如果資料量很大,比如幾萬條資料,放在一個頁面顯示的話顯然不友好,這時候就需要採用分頁顯示的形式,如每次只顯示10條資料
要實現分頁功能,實際上就是從結果集中顯示第1~10條記錄作為第1頁,顯示第11~20條記錄作為第2頁,以此類推
因此,分頁實際上就是從結果集中截取出第M~N條記錄
二、如何實現
前端實現分頁功能,需要後端返回必要的資料,如總的頁數,總的資料量,當前頁,當前的資料
{
"totalCount":1836,//總的條數
"totalPages":92,//總頁數
"currentPage":1//當前頁數
"data":[//當前頁的資料
{
...
}
]
後端採用mysql
前端向後端傳送目標的頁碼page
以及每頁顯示資料的數量pageSize
,預設情況每次取10條資料,則每一條資料的起始位置start
為:
conststart=(page-1)*pageSize
當確定了limit
和start
的值後,就能夠確定SQL
語句:
constsql=`SELECT*FROMrecordlimit${pageSize}OFFSET${start};`
上述SQL
語句表達的意思為:擷取從start
到start
+pageSize
之間(左閉右開)的資料
關於查詢資料總數的SQL
語句為,record
為表名:
SELECT COUNT(*) FROM record
因此後端的處理邏輯為:
- 獲取使用者引數頁碼數page和每頁顯示的數目 pageSize ,其中page 是必須傳遞的引數,pageSize為可選引數,預設為10
- 編寫 SQL 語句,利用 limit 和 OFFSET 關鍵字進行分頁查詢
- 查詢資料庫,返回總資料量、總頁數、當前頁、當前頁資料給前端
程式碼如下所示:
router.all('/api',function(req,res,next){
varparam='';
//獲取引數
if(req.method=="POST"){
param=req.body;
}else{
param=req.query||req.params;
}
if(param.page==''||param.page==null||param.page==undefined){
res.end(JSON.stringify({msg:'請傳入引數page',status:'102'}));
return;
}
constpageSize=param.pageSize||10;
conststart=(param.page-1)*pageSize;
constsql=`SELECT*FROMrecordlimit${pageSize}OFFSET${start};`
pool.getConnection(function(err,connection){
if(err)throwerr;
connection.query(sql,function(err,results){
connection.release();
if(err){
throwerr
}else{
//計算總頁數
varallCount=results[0][0]['COUNT(*)'];
varallPage=parseInt(allCount)/20;
varpageStr=allPage.toString();
//不能被整除
if(pageStr.indexOf('.')>0){
allPage=parseInt(pageStr.split('.')[0])+1;
}
varlist=results[1];
res.end(JSON.stringify({msg:'操作成功',status:'200',totalPages:allPage,currentPage:param.page,totalCount:allCount,data:list}));
}
})
})
});
三、總結
通過上面的分析,可以看到分頁查詢的關鍵在於,要首先確定每頁顯示的數量pageSize
,然後根據當前頁的索引pageIndex
(從1開始),確定LIMIT
和OFFSET
應該設定的值:
- LIMIT 總是設定為 pageSize
- OFFSET 計算公式為 pageSize * (pageIndex - 1)
確定了這兩個值,就能查詢出第N
頁的資料
參考文獻
- https://www.liaoxuefeng.com/wiki/1177760294764384/1217864791925600
- https://vue3js.cn/interview/