数据库:分页
介绍
在其他框架中,分页可能非常痛苦。我们希望 Laravel 的分页方法能带来一股清新的气息。Laravel 的分页器与 查询生成器 和 Eloquent ORM 并提供方便、易于使用的零配置数据库记录分页功能。
默认情况下,分页器生成的 HTML 与 Tailwind CSS 框架 ;但是,Bootstrap 分页支持也可用。
Tailwind JIT
如果你正在使用 Laravel 的默认 Tailwind 分页视图和 Tailwind JIT 引擎,则应确保应用程序的
tailwind.config.js
文件的
content
关键引用了 Laravel 的分页视图,以便它们的 Tailwind 类不会被清除:
1
内容: [2
‘
./资源/**/*.blade.php
‘
,3
‘
./资源/**/*.js
‘
,4
‘
./资源/**/*.vue
‘
,5
‘
./vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php
‘
,6
],
基本用法
对查询生成器结果进行分页
有几种方法可以对项目进行分页。最简单的方法是使用
paginate
方法上的
查询生成器
或
Eloquent 查询
。这
paginate
方法会自动根据用户当前正在查看的页面设置查询的“限制”和“偏移量”。默认情况下,当前页面通过
page
HTTP 请求中的查询字符串参数。此值由 Laravel 自动检测,并自动插入到分页器生成的链接中。
在此示例中,传递给
paginate
method 是您希望“每页”显示的项目数。在本例中,我们指定我们希望显示
15
每页项目数:
1
23
命名空间
应用程序\Http\控制器;45
使用
应用程序\Http\控制器\
控制器
;6
使用
照亮\支撑\外墙\
数据库
;7
使用
照亮\查看\
看法
;89
班级
用户控制器
延伸
控制器10
{11
/**12
* 显示所有应用程序用户。13
*/14
民众
功能
指数
()
:
看法15
{16
返回
看法
(
‘
用户索引
‘
,
[17
‘
用户
‘
=>
数据库
::
桌子
(
‘
用户
‘
)
->
分页
(
15
)18
]);19
}20
}
简单分页
这
paginate
方法在从数据库检索记录之前计算查询匹配的记录总数。这样做是为了让分页器知道总共有多少页记录。但是,如果您不打算在应用程序的 UI 中显示总页数,则记录计数查询是不必要的。
因此,如果你只需要在应用程序的 UI 中显示简单的“下一个”和“上一个”链接,则可以使用
simplePaginate
方法执行单个有效的查询:
1
$用户
=
数据库
::
桌子
(
‘
用户
‘
)
->
简单分页
(
15
(英文):
对 Eloquent 结果进行分页
您也可以分页
雄辩
查询。在此示例中,我们将分页
App\Models\User
模型并表明我们计划每页显示 15 条记录。如您所见,语法与分页查询生成器结果几乎相同:
1
使用
应用程序\模型\
用户
;23
$用户
=
用户
::
分页
(
15
(英文):
当然,你可以致电
paginate
在查询中设置其他约束后的方法,例如
where
条款:
1
$用户
=
用户
::
在哪里
(
‘
投票
‘
,
‘
>
‘
,
100
)
->
分页
(
15
(英文):
您还可以使用
simplePaginate
对 Eloquent 模型进行分页时的方法:
1
$用户
=
用户
::
在哪里
(
‘
投票
‘
,
‘
>
‘
,
100
)
->
简单分页
(
15
(英文):
类似地,您可以使用
cursorPaginate
对 Eloquent 模型进行光标分页的方法:
1
$用户
=
用户
::
在哪里
(
‘
投票
‘
,
‘
>
‘
,
100
)
->
光标分页
(
15
(英文):
每页有多个分页器实例
有时您可能需要在应用程序渲染的单个屏幕上渲染两个单独的分页器。但是,如果两个分页器实例都使用
page
查询字符串参数来存储当前页面,两个分页器将发生冲突。为了解决此冲突,您可以通过提供给分页器的第三个参数传递要用于存储分页器当前页面的查询字符串参数的名称
paginate
,
simplePaginate
, 和
cursorPaginate
方法:
1
使用
应用程序\模型\
用户
;23
$用户
=
用户
::
在哪里
(
‘
投票
‘
,
‘
>
‘
,
100
)
->
分页
(4
每页美元
=
15
,
$列
=
[
‘
*
‘
],
$页面名称
=
‘
用户
‘5
(英文):
光标分页
尽管
paginate
和
simplePaginate
使用 SQL“offset”子句创建查询,游标分页通过构建“where”子句来比较查询中包含的有序列的值,从而提供所有 Laravel 分页方法中最高效的数据库性能。这种分页方法特别适合大型数据集和“无限”滚动用户界面。
与基于偏移量的分页(分页器生成的 URL 的查询字符串中包含页码)不同,基于游标的分页在查询字符串中放置“游标”字符串。游标是一个编码字符串,其中包含下一个分页查询应开始分页的位置以及分页的方向:
1
http://本地主机/用户?光标=eyJpZCI6MTUsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0
您可以通过以下方式创建基于游标的分页器实例
cursorPaginate
查询生成器提供的方法。此方法返回
Illuminate\Pagination\CursorPaginator
:
1
$用户
=
数据库
::
桌子
(
‘
用户
‘
)
->
orderBy
(
‘
ID
‘
)
->
光标分页
(
15
(英文):
检索到游标分页器实例后,您可以
显示分页结果
就像您通常使用
paginate
和
simplePaginate
方法。有关光标分页器提供的实例方法的更多信息,请参阅
光标分页器实例方法文档
。
您的查询必须包含“order by”子句才能利用游标分页。此外,查询排序所依据的列必须属于您要分页的表。
光标与偏移分页
为了说明偏移分页和游标分页之间的区别,让我们来查看一些示例 SQL 查询。以下两个查询都将显示“第二页”结果
users
表格排序依据
id
:
1
# 偏移分页...2
选择
*
从
用户
排序依据
ID
升序
限制
15
抵消
15
;34
#
光标
分页...5
选择
*
从
用户
在哪里
ID
>
15
排序依据
ID
升序
限制
15
;
游标分页查询相对于偏移分页查询有以下优点:
- 对于大型数据集,如果“order by”列已编入索引,则游标分页将提供更好的性能。这是因为“offset”子句会扫描所有先前匹配的数据。
- 对于频繁写入的数据集,如果最近在用户当前正在查看的页面中添加或删除了结果,则偏移分页可能会跳过记录或显示重复项。
但是,游标分页有以下限制:
- 喜欢
simplePaginate
,光标分页只能显示“下一页”和“上一页”链接,不支持生成带页码的链接。 - 它要求排序至少基于一个唯一列或唯一列的组合。具有
null
值不受支持。 - “order by”子句中的查询表达式只有当它们有别名并且也添加到“select”子句中时才受支持。
- 不支持带有参数的查询表达式。
手动创建分页器
有时你可能希望手动创建分页实例,并向其传递内存中已有的项目数组。你可以通过创建
Illuminate\Pagination\Paginator
,
Illuminate\Pagination\LengthAwarePaginator
或者
Illuminate\Pagination\CursorPaginator
例如,这取决于您的需要。
这
Paginator
和
CursorPaginator
类不需要知道结果集中的项目总数;然而,正因为如此,这些类没有检索最后一页索引的方法。
LengthAwarePaginator
接受与
Paginator
;但是,它需要计算结果集中的项目总数。
换句话说,
Paginator
对应于
simplePaginate
查询生成器上的方法,
CursorPaginator
对应于
cursorPaginate
方法,以及
LengthAwarePaginator
对应于
paginate
方法。
手动创建分页器实例时,您应该手动“切片”传递给分页器的结果数组。如果您不确定如何执行此操作,请查看 数组切片 PHP 函数。
自定义分页 URL
默认情况下,分页器生成的链接将与当前请求的 URI 匹配。但是,分页器的
withPath
方法允许您自定义分页器在生成链接时使用的 URI。例如,如果您希望分页器生成如下链接
http://example.com/admin/users?page=N
,你应该通过
/admin/users
到
withPath
方法:
1
使用
应用程序\模型\
用户
;23
路线
::
得到
(
‘
/用户
‘
,
功能
()
{4
$用户
=
用户
::
分页
(
15
(英文):56
$用户
->
withPath
(
‘
/管理员/用户
‘
(英文):78
//
...9
});
附加查询字符串值
您可以使用以下方式附加到分页链接的查询字符串中:
appends
方法。例如,追加
sort=votes
对于每个分页链接,你应该进行以下调用
appends
:
1
使用
应用程序\模型\
用户
;23
路线
::
得到
(
‘
/用户
‘
,
功能
()
{4
$用户
=
用户
::
分页
(
15
(英文):56
$用户
->
附加
([
‘
种类
‘
=>
‘
投票
‘
]);78
//
...9
});
您可以使用
withQueryString
方法,如果您想要将当前请求的所有查询字符串值附加到分页链接:
1
$用户
=
用户
::
分页
(
15
)
->
带有查询字符串
();
附加哈希片段
如果你需要将“哈希片段”附加到分页器生成的 URL,则可以使用
fragment
方法。例如,追加
#users
在每个分页链接的末尾,你应该调用
fragment
像这样的方法:
1
$用户
=
用户
::
分页
(
15
)
->
分段
(
‘
用户
‘
(英文):
显示分页结果
当调用
paginate
方法,您将收到一个实例
Illuminate\Pagination\LengthAwarePaginator
,同时调用
simplePaginate
方法返回一个实例
Illuminate\Pagination\Paginator
。最后,调用
cursorPaginate
方法返回一个实例
Illuminate\Pagination\CursorPaginator
。
这些对象提供了几种描述结果集的方法。除了这些辅助方法之外,分页器实例还是迭代器,可以循环为数组。因此,检索结果后,您可以使用以下方法显示结果并呈现页面链接: 刀刃 :
1
<
div
班级
=
“
容器
“
>2
@foreach
(
$用户
作为
$用户
)3
{{
$用户
->名称
}}4
@endforeach5
</
div
>67
{{
$用户
->
链接
()
}}
这
links
方法将呈现结果集中其余页面的链接。每个链接都已包含正确的
page
查询字符串变量。请记住,由
links
方法兼容
Tailwind CSS 框架
。
调整分页链接窗口
当分页器显示分页链接时,会显示当前页码以及当前页前后三页的链接。使用
onEachSide
方法,您可以控制在分页器生成的中间滑动链接窗口内当前页面两侧显示多少个附加链接:
1
{{
$用户
->
每一方
(
5
)
->
链接
()
}}
将结果转换为 JSON
Laravel 分页器类实现
Illuminate\Contracts\Support\Jsonable
接口契约并公开
toJson
方法,因此将分页结果转换为 JSON 非常容易。您还可以通过从路由或控制器操作返回分页器实例将其转换为 JSON:
1
使用
应用程序\模型\
用户
;23
路线
::
得到
(
‘
/用户
‘
,
功能
()
{4
返回
用户
::
分页
();5
});
分页器的 JSON 将包含以下元信息:
total
,
current_page
,
last_page
等。结果记录可通过
data
JSON 数组中的键。以下是从路由返回分页器实例所创建的 JSON 示例:
1
{2
“
全部的
“
:
50
,3
“
每页
“
:
15
,4
“
当前页
“
:
1
,5
“
最后一页
“
:
4
,6
“
首页网址
“
:
“
http://laravel.app?page=1
“
,7
“
最后一页的 URL
“
:
“
http://laravel.app?page=4
“
,8
“
下一页网址
“
:
“
http://laravel.app?page=2
“
,9
“
上一页的 URL
“
:
无效的
,10
“
小路
“
:
“
http://laravel.app
“
,11
“
从
“
:
1
,12
“
到
“
:
15
,13
“
数据
“
:[14
{15
//
记录...16
},17
{18
//
记录...19
}20
]21
}
自定义分页视图
默认情况下,显示分页链接的视图与
Tailwind CSS
框架。但是,如果您不使用 Tailwind,您可以自由定义自己的视图来呈现这些链接。调用
links
方法,您可以将视图名称作为该方法的第一个参数传递:
1
{{
$分页器
->
链接
(
‘
视图名称
‘
)
}}23
将附加数据传递至视图...
-->4
{{
$分页器
->
链接
(
‘
视图名称
‘
,[
‘
富
‘
=>
‘
酒吧
‘
])
}}
不过,自定义分页视图最简单的方法是将其导出到您的
resources/views/vendor
目录使用
vendor:publish
命令:
1
php
工匠
供应商:发布
--tag=laravel-pagination
此命令将视图放置在应用程序的
resources/views/vendor/pagination
目录。
tailwind.blade.php
此目录中的文件对应于默认分页视图。您可以编辑此文件来修改分页 HTML。
如果你想指定不同的文件作为默认分页视图,你可以调用分页器的
defaultView
和
defaultSimpleView
方法
boot
你的方法
App\Providers\AppServiceProvider
班级:
1
23
命名空间
应用程序\提供商;45
使用
照亮\分页\
页
;6
使用
照亮\支持\
服务提供者
;78
班级
应用服务提供商
延伸
服务提供者9
{10
/**11
* 引导任何应用服务。12
*/13
民众
功能
引导
()
:
空白14
{15
页
::
默认视图
(
‘
视图名称
‘
(英文):1617
页
::
默认简单视图
(
‘
视图名称
‘
(英文):18
}19
}
使用 Bootstrap
Laravel 包含使用以下方式构建的分页视图
引导 CSS
。要使用这些视图而不是默认的 Tailwind 视图,您可以调用分页器的
useBootstrapFour
或者
useBootstrapFive
方法
boot
你的方法
App\Providers\AppServiceProvider
班级:
1
使用
照亮\分页\
页
;23
/**4
* 引导任何应用服务。5
*/6
民众
功能
引导
()
:
空白7
{8
页
::
使用Bootstrap5
();9
页
::
使用Bootstrap4
();10
}
Paginator / LengthAwarePaginator 实例方法
每个分页器实例通过以下方法提供额外的分页信息:
方法 | 描述 |
---|---|
$paginator->count() |
获取当前页面的项目数。 |
$paginator->currentPage() |
获取当前页码。 |
$paginator->firstItem() |
获取结果中第一项的结果编号。 |
$paginator->getOptions() |
获取分页器选项。 |
$paginator->getUrlRange($start, $end) |
创建一系列分页 URL。 |
$paginator->hasPages() |
确定是否有足够的项目可以拆分成多个页面。 |
$paginator->hasMorePages() |
确定数据存储中是否还有更多项目。 |
$paginator->items() |
获取当前页面的项目。 |
$paginator->lastItem() |
获取结果中最后一项的结果编号。 |
$paginator->lastPage() |
获取最后一页的页码。(使用
simplePaginate
)。 |
$paginator->nextPageUrl() |
获取下一页的 URL。 |
$paginator->onFirstPage() |
确定分页器是否在第一页。 |
$paginator->perPage() |
每页显示的项目数。 |
$paginator->previousPageUrl() |
获取上一页的 URL。 |
$paginator->total() |
确定数据存储中匹配项的总数。(使用
simplePaginate
)。 |
$paginator->url($page) |
获取给定页码的 URL。 |
$paginator->getPageName() |
获取用于存储页面的查询字符串变量。 |
$paginator->setPageName($name) |
设置用于存储页面的查询字符串变量。 |
$paginator->through($callback) |
使用回调转换每个项目。 |
Cursor Paginator 实例方法
每个游标分页器实例通过以下方法提供额外的分页信息:
方法 | 描述 |
---|---|
$paginator->count() |
获取当前页面的项目数。 |
$paginator->cursor() |
获取当前光标实例。 |
$paginator->getOptions() |
获取分页器选项。 |
$paginator->hasPages() |
确定是否有足够的项目可以拆分成多个页面。 |
$paginator->hasMorePages() |
确定数据存储中是否还有更多项目。 |
$paginator->getCursorName() |
获取用于存储游标的查询字符串变量。 |
$paginator->items() |
获取当前页面的项目。 |
$paginator->nextCursor() |
获取下一组项目的光标实例。 |
$paginator->nextPageUrl() |
获取下一页的 URL。 |
$paginator->onFirstPage() |
确定分页器是否在第一页。 |
$paginator->onLastPage() |
确定分页器是否在最后一页。 |
$paginator->perPage() |
每页显示的项目数。 |
$paginator->previousCursor() |
获取前一组项目的光标实例。 |
$paginator->previousPageUrl() |
获取上一页的 URL。 |
$paginator->setCursorName() |
设置用于存储游标的查询字符串变量。 |
$paginator->url($cursor) |
获取给定光标实例的 URL。 |