[Laravel] Api 列表分页详解

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

内容简介:[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();
  }
 

轻松搞定

总结归纳

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


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

查看所有标签

猜你喜欢:

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

Mastering Regular Expressions, Second Edition

Mastering Regular Expressions, Second Edition

Jeffrey E F Friedl / O'Reilly Media / 2002-07-15 / USD 39.95

Regular expressions are an extremely powerful tool for manipulating text and data. They have spread like wildfire in recent years, now offered as standard features in Perl, Java, VB.NET and C# (and an......一起来看看 《Mastering Regular Expressions, Second Edition》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具