node用express写后端restful接口实战八:分页查询

it2023-01-21  59

分页原理

这一集要实现的是数据分页功能。分页功能的实现,是由 SQL 语句中 limit 的两个参数来实现的。大家一起来看一个表格,先假设每页要显示 10 条数据。

当前页数(currentPage)从哪里开始(offset)每页显示多少条(pageSize)10102101032010 第一页,要从头开始,就是从 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}); */ })
最新回复(0)