分頁原理
這一集要實現的是數據分頁功能。分頁功能的實現,是由 SQL
語句中 limit
的兩個參數來實現的。大家一起來看一個表格,先假設每頁要顯示 10
條數據。
當前頁數(currentPage) | 從哪里開始(offset) | 每頁顯示多少條(pageSize) |
---|---|---|
1 | 0 | 10 |
2 | 10 | 10 |
3 | 20 | 10 |
- 第一頁,要從頭開始,就是從
0
開始,往后找10
條數據。這就是第一頁要顯示的內容。 - 第二頁,就從
10
開始,還是再往后找10條數據
。 - 其他依次類推了。
大家仔細觀察下這個表格,動動你聰明的小腦袋。看下中間這個參數 offset
,和其他兩個參數之間的關系。
offset = (currentPage - 1) * pageSize
我給大家一個公式,大家看看是不是對的。其中 pageSize
參數是固定不動的,就是 10
。offset = (當前頁數 - 1) * 每頁條數
。如果你搞清楚了這個規律,現在咱們就可以正式來寫分頁相關代碼了。
分頁實現
第一步:當前頁數(currentPage)
先來定義下 當前頁數(currentPage)
,如果用戶傳了這個參數,那就以用戶傳的為准。如果用戶沒傳,那就默認是 第一頁
。另外,因為用戶傳遞過來的數據,都是字符串,所以咱們用 parseInt
轉換一下。
var currentPage = parseInt(req.query.currentPage) || 1;
這種寫法,可能有的同學感覺比較陌生,其實它就相當於
var currentPage = parseInt(req.query.currentPage);
if (!currentPage) {
currentPage = 1;
}
這是這種寫法,不夠簡潔,所以我們就換成了上面,這種 短路
的寫法了。
第二步:每頁顯示多少條(pageSize)
接着來定義,每頁顯示多少條(pageSize)。和上面一樣的,如果用戶不傳遞參數過來,也給它一個默認值。因為咱們數據庫里的數據比較少,一共也只插入了 4 條進去,就讓它默認,每頁顯示兩條數據。
var pageSize = parseInt(req.query.pageSize) || 2;
第三步:findAndCountAll、offset 與 limit
這兩個參數定義好了以后,現在就要來調整查詢部分的代碼了。第一個是要將 findAll
改為 findAndCountAll
,區別是 findAndCountAll
能返回總的記錄數。接收值的 articles
改為 result
,因為現在不僅僅有文章列表
了,還有記錄總數
。
接着要做的就是,添加上 offset
和 limit
參數。offset
對應的值,就是剛才咱們研究出來的計算公式。而 limit
就是 pageSize
。
var result = await models.Article.findAndCountAll({
order:[['id', 'DESC']],
where: where,
offset: (currentPage - 1) * pageSize,
limit: pageSize
});
第四步:響應出分頁的 json
查詢完成后,最后要做的就是響應出json
格式了。先來看看, result
里有些什么東西。
return res.json(result);
count
里,保存的就是記錄總數了,咱們數據庫一共就是只有4
條記錄rows
里,存的才是文章列表。
看到結構后,現在先屏蔽掉調試的代碼。
res.json
里,先把 articles
的值,改為 result.rows
,這樣文章列表就有了。
第五步:返回分頁數據
至於分頁,一般用 Element UI 這類框架,來實現前端分頁,就需要三個參數。先來定義一個 pagination
,包含的值分別是 currentPage
、pageSize
和 total
res.json({
articles: result.rows,
pagination: {
currentPage: currentPage,
pageSize: pageSize,
// 一共有多少條記錄
total: result.count
}
});
測試
整體代碼就已經完成了,現在來嘗試查詢一下看看。http://localhost:3000/articles
果然,可以看到分頁相關的參數了。
再來分別嘗試下其他分頁參數,http://localhost:3000/articles?currentPage=1&pageSize=3,當前是第一頁,每頁顯示 3 條。
http://localhost:3000/articles?currentPage=2&pageSize=3,再來將 currentPage
改為 2
。這樣顯示的就是第二頁的數據了。
分頁功能,到這里就已經完美實現了。
完整代碼 routes/articles.js
router.get('/',async function(req,res,next){
// res.json({hello:'sky'})
// 普通寫法讀取文章數據
/*models.Article.findAll().then(articles=>{
res.json({articles:articles});
})*/
//定義模糊查詢對象
var where={}; //搜索空對象
var title=req.query.title; //獲取搜索標題
//如果請求參數包含title則向where里添加一個模糊查詢的屬性
if(title){
where.title={
[Op.like]:"%" + title + "%"
}
}
// 分頁定義
// 當前頁是第幾頁
var currentPage = parseInt(req.query.currentPage) || 1;
//每頁面顯示多少條數據
var pageSize = parseInt(req.query.pageSize) || 2;
var result = await models.Article.findAndCountAll({
order:[['id', 'DESC']],
where: where,
offset: (currentPage - 1) * pageSize,
limit: pageSize
});
// return res.json(result);
return res.json({
articles: result.rows,
pagination: {
currentPage: currentPage,
pageSize: pageSize,
// 一共有多少條記錄
total: result.count
}
});
/*異步讀取文章數據
var articles=await models.Article.findAll({
// order:[['id','DESC']], //數據按id降序排列
order:[['id','ASC']], //正序排列,默認方式
where:where,
});
res.json({articles:articles});
*/
})