deepdiver / laravel-cursor-paginator
为 Laravel 8 提供游标分页
v2.0.0
2020-07-27 13:25 UTC
Requires (Dev)
- orchestra/testbench: ^5.3
- phpunit/phpunit: ^9.2
README
在您的 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 文件。