内容简介:[Laravel] Api 列表分页详解
引言
上一篇文章提到,文章评论列表需要实现分页。那么分页该如何实现?以及,为什么要分页?
分页的原因
使用分页的原因很简单,在数据量非常庞大的情况下,不可能一次性把所有数据一次性返回给前端,不然前端就卡死了。所以我们使用分页的最终目的,就是优化用户的使用体验,加载的速度快,每一页数据量合理,不能让用户觉得觉得没看够,也不能看起来没玩没了。
分页的方式
page分页分析
比较容易理解的一种分页方式。
你可以选择page,或者点击上一页,或者点击下一页来跳转到不同的页面,只要给服务器传一个 page 参数即可实现。
服务器这边拿到page之后,使用limit offset来获取相应的数据。如果使用了框架,可以使用框架自带的分页服务。拿 Laravel 来说,使用 paginate()即可实现分页效果,非常的方便。这种分页方式有利有弊。
优点:
-
实现简单,方便,易于理解。
-
可以快速浏览。比如直接从第一页跳转到第十页。
-
对主键的顺序性要求不大。
缺点:
-
存在一个 limit 1000 的问题。当一次性跳转非常多页面时,limit offset 方法实现的分页会存在很多次多余的查表操作,严重的影响了查询速度。
-
比较适合用在桌面端。手机端不方便。
缺点 1 是可以优化的,比如使用子查询。有兴趣的伙伴可以查一查资料。
根据id分页
理解稍微有一点点困难。常见的使用场景就是,下拉刷新,上拉刷新。比如刷知乎,刷微博,直接往下拉,就会一直进入下一页,刷起来没完没了。
这里前端需要提供的参数,是一个 ID 值。如果是下拉刷新,需要提供这一页最后一条数据的 ID;如果是上拉刷新,需要提供这一页第一条数据的 ID。拿下拉刷新举例,服务器拿到 ID 后,查找 id < ID的数据就可以了。上拉刷新也是一样的道理,把 ‘<’ 换成 ‘>’ 而已。这种分页也是有利有弊:
优点:
-
利用主键进行查询,效率高,速度快。
-
适用于手机端应用。
缺点:
-
要求 ID 是顺序结构。
-
无法快速浏览,只能一页一页的来。
下面上一点具体的代码,帮助大家理解吧。
分页的具体实现方法
page分页的实现办法
基于 Laravel 框架,我们可以使用
public function getAnswerListById($questionId, $pageSize) { $answers = Answer::where('question_id', '=', $questionId) ->join('articles', 'answers.article_id', '=', 'articles.id') ->orderBy('count_thanks', 'desc') ->paginate($pageSize); return $answers; }
page 参数,框架会自动加上,所以实现起来十分方便,只要传一个 page_size 就行了。paginate 的源码实现分析,可以参考 这篇文章
但是使用自带的 paginate 分页会有一个坑,返回的数据结构会增加一个 meta ,是分页的具体信息。这是不可容忍的。我们写 Api,要求做到:要什么,给什么,绝不缺少,绝不多余。meta 就属于多余,我们要去除之。
public function index(Request $request, $questionId) { $pageSize = $request->input('page_size', 10); $answers = $this->answerInterface->getAnswerListById($questionId, $pageSize); return $this->response->collection(collect($answers->items()), new AnswerListTransformer()); }
注意: collect($answer->items()) 这句话,成功去掉了我们不想要的 meta, 留下了我们需要的 data。
id分页的实现办法
某大佬写了一个库,可以轻松实现 ID 分页。 github地址 。不过实现起来很方便,直接手写也没问题。
public function getArticleCommentsById($articleId, $pageSize, $maxId, $sinceId) { $pageSize = !empty($pageSize) ? $pageSize : 10; $condition = array( 'article_id' => $articleId, 'is_evaluation' => "0", ); $comments = ArticleComment::where($condition); if($maxId) { $comments->where('id', '>', $maxId); } else if($sinceId) { $comments->where('id', '<', $sinceId); } return $comments ->orderBy('id', 'desc') ->take($pageSize) ->get(); }
轻松搞定
总结归纳
同一个问题会有多种不同的解决方案,每一种解决方案也是多种多样的。要学会思考优点和缺点,尝试优化。然后根据不同的使用场合,挑选适合的解决方案。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- python中列表的sort方法使用详解
- C#列表到列表转换
- Python笔记(二):列表+列表数据处理+函数
- python创建列表和向列表添加元素方法
- 在Bootstrap开发框架中使用bootstrapTable表格插件和jstree树形列表插件时候,对树列表条件和查询...
- Python 列表(List)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。