[Laravel] Api 列表分页详解

栏目: 编程语言 · PHP · 发布时间: 6年前

内容简介:[Laravel] Api 列表分页详解

引言

上一篇文章提到,文章评论列表需要实现分页。那么分页该如何实现?以及,为什么要分页?

分页的原因

使用分页的原因很简单,在数据量非常庞大的情况下,不可能一次性把所有数据一次性返回给前端,不然前端就卡死了。所以我们使用分页的最终目的,就是优化用户的使用体验,加载的速度快,每一页数据量合理,不能让用户觉得觉得没看够,也不能看起来没玩没了。

分页的方式

page分页分析

比较容易理解的一种分页方式。

[Laravel] Api 列表分页详解

你可以选择page,或者点击上一页,或者点击下一页来跳转到不同的页面,只要给服务器传一个 page 参数即可实现。

服务器这边拿到page之后,使用limit offset来获取相应的数据。如果使用了框架,可以使用框架自带的分页服务。拿 Laravel 来说,使用 paginate()即可实现分页效果,非常的方便。这种分页方式有利有弊。

优点:

  1. 实现简单,方便,易于理解。

  2. 可以快速浏览。比如直接从第一页跳转到第十页。

  3. 对主键的顺序性要求不大。

缺点:

  1. 存在一个 limit 1000 的问题。当一次性跳转非常多页面时,limit offset 方法实现的分页会存在很多次多余的查表操作,严重的影响了查询速度。

  2. 比较适合用在桌面端。手机端不方便。

缺点 1 是可以优化的,比如使用子查询。有兴趣的伙伴可以查一查资料。

根据id分页

理解稍微有一点点困难。常见的使用场景就是,下拉刷新,上拉刷新。比如刷知乎,刷微博,直接往下拉,就会一直进入下一页,刷起来没完没了。

这里前端需要提供的参数,是一个 ID 值。如果是下拉刷新,需要提供这一页最后一条数据的 ID;如果是上拉刷新,需要提供这一页第一条数据的 ID。拿下拉刷新举例,服务器拿到 ID 后,查找 id < ID的数据就可以了。上拉刷新也是一样的道理,把 ‘<’ 换成 ‘>’ 而已。这种分页也是有利有弊:

优点:

  1. 利用主键进行查询,效率高,速度快。

  2. 适用于手机端应用。

缺点:

  1. 要求 ID 是顺序结构。

  2. 无法快速浏览,只能一页一页的来。

下面上一点具体的代码,帮助大家理解吧。

分页的具体实现方法

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();
  }
 

轻松搞定

总结归纳

同一个问题会有多种不同的解决方案,每一种解决方案也是多种多样的。要学会思考优点和缺点,尝试优化。然后根据不同的使用场合,挑选适合的解决方案。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

大视觉创意宝典

大视觉创意宝典

2008-8 / 28.00元

《大视觉创意宝典:网页设计》主要内容:将优秀的网页分为设计、卡通、教育、金融、通讯、企业、房地产、娱乐等十四个章节,并详尽解析其页面布局、配色参考、设计特色及细节元素。丛书编写以设计基础的角度出发,具备速查、参照、案头工具书等功能。一起来看看 《大视觉创意宝典》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器