deepdiver/laravel-cursor-paginator

为 Laravel 8 提供游标分页

v2.0.0 2020-07-27 13:25 UTC

This package is auto-updated.

Last update: 2024-09-07 21:36:15 UTC


README

Build Status

在您的 Eloquent 模型和查询构建器中轻松实现基于游标的分页,阅读这篇文章了解游标分页的好处以及它试图解决的问题。

还有一个 cursor-pagination 包,但遗憾的是它不支持检索前一页或多列排序,这就是我决定创建这个包的原因。

功能

  • 根据列排序自动分页。
  • 支持多列排序,这使得具有确定性的行序列变得容易。
  • 检测模型是否具有日期转换。
  • 多个游标方向
    • before: 返回游标之前的项。
    • before_i: 返回游标之前的项(包括游标处的项)。
    • after: 返回游标之后的项。
    • after_i: 返回游标之后的项(包括游标处的项)。

安装

首先通过 composer 安装此包

composer require amrnn/laravel-cursor-paginator

您可以选择发布配置文件

php artisan vendor:publish --provider="Amrnn\CursorPaginator\PaginatorServiceProvider"

注册服务提供者

该包会自动注册自己,但如果需要,您可以手动添加服务提供者。

// config/app.php

'providers' => [
    // ...
    Amrnn\CursorPaginator\PaginatorServiceProvider::class,
];

使用方法

此包提供了一个 cursorPaginate() 方法,您可以在 Eloquent 模型或查询构建器上调用该方法

Route::get('/posts', function() {
    return Post::select('id')->orderBy('id', 'desc')->cursorPaginate(5);
})

它将返回类似以下内容

{
    /**
    * the result items
    */
    "data": [{"id": 10},{"id": 9},{"id": 8},{"id": 7},{"id": 6}],

    /**
    * number of items per page
    */
    "per_page": 5,

    /**
    * total items in result set for your query
    */
    "total": 10,

    /**
    * the following boundary item if you continue to paginate in this direction
    */
    "next_item": { "id": 5 },

    /**
    * navigation urls, you can change the cursor names in the url query string by
    * editing the (directions) array in config file.
    */
    "first_page_url": "https://:8000/posts?after_i=10",
    "last_page_url": "https://:8000/posts?before_i=1",
    "next_page_url": "https://:8000/posts?after=6",
    "prev_page_url": "https://:8000/posts?before=10",

    /*
    * these provide the cursor data structures.
    * they are given in case you want to construct the url manually,
    * but usually you will  just use the urls shown above.
    */
    "current_page": {...},
    "first_page": {...},
    "last_page": {...},
    "next_page": {...},
    "previous_page": {...},

    /*
    * determine if there are more next/previous items
    */
    "has_next": true,
    "has_previous": false,

}

选项

您可以将可选的第一个参数传递给 paginateCursor() 以指定每页的项目数(如果为空,则使用配置文件中的默认值)

// will return 10 items per page
Post::orderBy('id')->cursorPaginate(10);

该包应通过检查您的模型自动确定日期转换。但是,如果您在普通的查询构建器上调用分页,则可能需要传递第二个参数,该参数告诉它有关日期转换的信息

// no need to specify date casts here
Post::orderBy('created_at')->cursorPaginate(10);

// must tell a plain query builder about the dates
DB::table('posts')
    ->orderBy('created_at')
    ->cursorPaginate(10, ['dates' => ['created_at']]);

多列

您可以根据多列排序,分页应按预期工作

Post::orderBy('created_at')->orderBy('id')->cursorPaginate();

Post::orderBy('created_at', 'desc')->orderBy('id', 'desc'')->cursorPaginate();

不建议在多列排序时混合方向(升序,降序)。这样做会使数据库的表索引难以使用。

注意事项

您要排序的所有列都必须出现在您的 select 语句中,例如以下内容将不起作用

Post::select('id')->orderBy('created_at')->cursorPaginate();

您必须执行以下任何一项

Post::select('id', 'created_at')->orderBy('created_at')->cursorPaginate();

// or

Post::orderBy('created_at')->cursorPaginate()

配置

return [
    /**
     *
     * Cursor direction names
     *
     * these appear in the url query string, change their mappings if you need to.
     * for example if you change:
     *
     * 'before' => 'b'
     *
     * then your urls might look like:
     * https://:8000/b=10 instead of https://:8000/before=10
     */
    'directions' => [
        'before' => 'before',
        'before_i' => 'before_i',
        'after' => 'after',
        'after_i' => 'after_i',
    ],

    /**
     * Whether to encode url query.
     *
     * If set to true then your urls might look like:
     * https://:8000/cursor=eyJhZnRlciI6M30 instead of https://:8000/after=3
     */
    'encode_cursor' => false,

    /**
     * Cursor url query name to use when `encode_cursor` set to is `true`.
     *
     * for example if you change:
     * 'encoded_cursor_name' => 'page-id'
     *
     * then your urls might look like:
     * https://:8000/page-id=eyJhZnRlciI6M30 instead of https://:8000/cursor=eyJhZnRlciI6M30
     */
    'encoded_cursor_name' => 'cursor',

    /**
     * Default number of items per page.
     *
     * This can be overridden by passing a first argument to the `cursorPaginate()` method.
     */
    'per_page' => 10,
];

许可证

本项目采用 MIT 许可证 - 有关详细信息,请参阅 LICENSE.md 文件。