lampager / lampager-laravel
Laravel的快速分页
v0.5.2
2023-03-15 07:56 UTC
Requires
- php: ^8.0
- ext-json: *
- illuminate/contracts: ^9.0 || ^10.0 || ^11.0
- illuminate/database: ^9.0 || ^10.0 || ^11.0
- illuminate/support: ^9.0 || ^10.0 || ^11.0
- lampager/lampager: ^0.4
Requires (Dev)
- nilportugues/sql-query-formatter: ^1.2.2
- orchestra/testbench: *
- orchestra/testbench-core: >=7.0
- phpunit/phpunit: >=9.5
README
Laravel的Lampager
不使用OFFSET进行快速分页
要求
- PHP:
^8.0 - Laravel:
^9.0 || ^10.0 || ^11.0 - lampager/lampager:
^0.4
安装
composer require lampager/lampager-laravel
基本用法
注册服务提供者。
config/app.php:
/* * Package Service Providers... */ Lampager\Laravel\MacroServiceProvider::class,
然后你可以从查询构建器、Eloquent构建器和关系中使用 ->lampager() 方法。
$cursor = [ 'id' => 3, 'created_at' => '2017-01-10 00:00:00', 'updated_at' => '2017-01-20 00:00:00', ]; $result = App\Post::whereUserId(1) ->lampager() ->forward() ->limit(5) ->orderByDesc('updated_at') // ORDER BY `updated_at` DESC, `created_at` DESC, `id` DESC ->orderByDesc('created_at') ->orderByDesc('id') ->seekable() ->paginate($cursor) ->toJson(JSON_PRETTY_PRINT);
这将运行优化的查询。
(
SELECT * FROM `posts`
WHERE `user_id` = 1
AND (
`updated_at` = '2017-01-20 00:00:00' AND `created_at` = '2017-01-10 00:00:00' AND `id` > 3
OR
`updated_at` = '2017-01-20 00:00:00' AND `created_at` > '2017-01-10 00:00:00'
OR
`updated_at` > '2017-01-20 00:00:00'
)
ORDER BY `updated_at` ASC, `created_at` ASC, `id` ASC
LIMIT 1
) UNION ALL (
SELECT * FROM `posts`
WHERE `user_id` = 1
AND (
`updated_at` = '2017-01-20 00:00:00' AND `created_at` = '2017-01-10 00:00:00' AND `id` <= 3
OR
`updated_at` = '2017-01-20 00:00:00' AND `created_at` < '2017-01-10 00:00:00'
OR
`updated_at` < '2017-01-20 00:00:00'
)
ORDER BY `updated_at` DESC, `created_at` DESC, `id` DESC
LIMIT 6
)
并且你会得到
{
"records": [
{
"id": 3,
"user_id": 1,
"text": "foo",
"created_at": "2017-01-10 00:00:00",
"updated_at": "2017-01-20 00:00:00"
},
{
"id": 5,
"user_id": 1,
"text": "bar",
"created_at": "2017-01-05 00:00:00",
"updated_at": "2017-01-20 00:00:00"
},
{
"id": 4,
"user_id": 1,
"text": "baz",
"created_at": "2017-01-05 00:00:00",
"updated_at": "2017-01-20 00:00:00"
},
{
"id": 2,
"user_id": 1,
"text": "qux",
"created_at": "2017-01-17 00:00:00",
"updated_at": "2017-01-18 00:00:00"
},
{
"id": 1,
"user_id": 1,
"text": "quux",
"created_at": "2017-01-16 00:00:00",
"updated_at": "2017-01-18 00:00:00"
}
],
"has_previous": false,
"previous_cursor": null,
"has_next": true,
"next_cursor": {
"updated_at": "2017-01-18 00:00:00",
"created_at": "2017-01-14 00:00:00",
"id": 6
}
}
资源集合
Lampager支持Laravel的API资源。
在资源和资源集合上使用辅助特性。
use Illuminate\Http\Resources\Json\JsonResource; use Lampager\Laravel\LampagerResourceTrait; class PostResource extends JsonResource { use LampagerResourceTrait; }
use Illuminate\Http\Resources\Json\ResourceCollection; use Lampager\Laravel\LampagerResourceCollectionTrait; class PostResourceCollection extends ResourceCollection { use LampagerResourceCollectionTrait; }
$posts = App\Post::lampager() ->orderByDesc('id') ->paginate(); return new PostResourceCollection($posts);
{ "data": [/* ... */], "has_previous": false, "previous_cursor": null, "has_next": true, "next_cursor": {/* ... */} }
类
注意:另请参阅lampager/lampager。
Paginator、Processor和PaginationResult可宏化。
API
注意:另请参阅lampager/lampager。
Paginator::__construct()
Paginator::create()
创建一个新的分页器实例。
但是如果你使用Laravel宏,则不需要直接实例化。
static Paginator create(QueryBuilder|EloquentBuilder|Relation $builder): static Paginator::__construct(QueryBuilder|EloquentBuilder|Relation $builder)
QueryBuilder表示\Illuminate\Database\Query\BuilderEloquentBuilder表示\Illuminate\Database\Eloquent\BuilderRelation表示\Illuminate\Database\Eloquent\Relation
Paginator::transform()
将Lampager查询转换为Illuminate构建器。
Paginator::transform(Query $query): QueryBuilder|EloquentBuilder|Relation
Paginator::build()
执行配置加转换。
Paginator::build(\Lampager\Contracts\Cursor|array $cursor = []): QueryBuilder|EloquentBuilder|Relation
Paginator::paginate()
执行配置加转换加处理。
Paginator::paginate(\Lampager\Contracts\Cursor|array $cursor = []): \Lampager\Laravel\PaginationResult
参数
(mixed)$cursor
一个包含$column => $value的关联数组或实现\Lampager\Contracts\Cursor的对象。它必须是all-or-nothing。- 对于初始页面,省略此参数或传递空数组。
- 对于后续页面,传递所有参数。不允许部分参数。
返回值
例如。
(使用\Illuminate\Database\Eloquent\Builder时的默认格式)
object(Lampager\Laravel\PaginationResult)#1 (5) { ["records"]=> object(Illuminate\Database\Eloquent\Collection)#2 (1) { ["items":protected]=> array(5) { [0]=> object(App\Post)#2 (26) { ... } [1]=> object(App\Post)#3 (26) { ... } [2]=> object(App\Post)#4 (26) { ... } [3]=> object(App\Post)#5 (26) { ... } [4]=> object(App\Post)#6 (26) { ... } } } ["hasPrevious"]=> bool(false) ["previousCursor"]=> NULL ["hasNext"]=> bool(true) ["nextCursor"]=> array(2) { ["updated_at"]=> string(19) "2017-01-18 00:00:00" ["created_at"]=> string(19) "2017-01-14 00:00:00" ["id"]=> int(6) } }
Paginator::useFormatter()
Paginator::restoreFormatter()
Paginator::process()
调用处理器方法。
Paginator::useFormatter(Formatter|callable $formatter): $this Paginator::restoreFormatter(): $this Paginator::process(\Lampager\Query $query, \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Collection $rows): \Lampager\Laravel\PaginationResult
PaginationResult::toArray()
PaginationResult::jsonSerialize()
将对象转换为数组。
重要:camelCase属性将转换为snake_case形式。
PaginationResult::toArray(): array PaginationResult::jsonSerialize(): array
PaginationResult::__call()
调用宏或集合方法。
PaginationResult::__call(string $name, array $args): mixed
例如。
PaginationResult::macro('foo', function () { return ...; }); $foo = $result->foo();
$first = $result->first();
