sergyjar / laravel-query-builder
一种简单的方法,在考虑过滤、排序和分页的情况下获取模型集合
Requires
- php: ^8.3
- illuminate/console: ^10.0|^11.0
- illuminate/container: ^10.0|^11.0
- illuminate/contracts: ^10.0|^11.0
- illuminate/database: ^10.0|^11.0
- illuminate/support: ^10.0|^11.0
- symfony/console: ^6.2.3|^7.0
- symfony/finder: ^6.2.3|^7.0
README
一种简单的方法,在考虑过滤、排序和分页的情况下获取模型集合。
注意:此包需要 PHP 8.3+ 和 Laravel/Eloquent 10+。
目录
安装
您可以使用以下命令将此包作为本地、按项目依赖项添加到项目中:
composer require sergyjar/laravel-query-builder
将包安装到您的项目中后,您需要发布配置并注册一个命令,这将有助于您进一步操作。为此,请运行此命令
php artisan vendor:publish --provider="Sergyjar\QueryBuilder\Providers\QueryBuilderServiceProvider"
这完成了安装阶段。现在您可以利用这些机会。
用法
命令
要使用构建器的功能,只剩几个步骤。首先,您需要为特定的模型创建一个构建器。您可以自己创建,但最简单的方法是运行以下命令
php artisan query-builder:make ModelName
此命令将自动找到具有传递名称的模型,并创建一个继承自基础构建器的文件。
该文件将在标准路径 App/QueryBuilders 中创建,名称为 ModelNameQueryBuilder
您也可以通过指定命令的可选参数来指定文件创建路径。
php artisan query-builder:make ModelName --path Path/For/File
或
php artisan query-builder:make ModelName -p Path/For/File
在两种情况下,都会在 App/Path/For/File 中创建一个文件。
ModelQueryBuilder
如果您使用了命令,它将创建一个类似这样的类。您也可以自己创建一个类似的类。
namespace App\Path\For\File; use App\Models\ModelName; use Sergyjar\QueryBuilder\AbstractQueryBuilder; class ModelNameQueryBuilder extends AbstractQueryBuilder { protected array $filterableFields = [ // ]; protected array $sortMap = [ // ]; protected function getModelClass(): string { return ModelName::class; } }
1. 过滤
您可以通过向 $filterableFields 数组中添加字段来启用过滤。字段名称可以传递为 camelCase 和 snake_case,主要的是字段名称与请求字段匹配。构建器本身将字段转换为 camelCase 并尝试调用一个类似于 whereFieldName 的作用域,其中 FieldName 是 $filterableFields 数组元素。
protected array $filterableFields = [ 'fieldName' ];
或
protected array $filterableFields = [ 'field_name' ];
如果您想使用不匹配模型字段的自定义过滤器,或者由于其他原因,可以定义一个将用于尝试调用作用域的 方法。在此方法中,您可以定义任何过滤条件。
示例
protected array $filterableFields = [ 'status' ]; public function status($value): void { if ($value == 'pending') { $this->query->whereStatus($value) } }
这完成了过滤设置,现在您可以根据自己的规则使用过滤器。
2. 排序
此构建器允许您定义一个排序字段的映射,您需要在 $sortMap 数组中定义。
protected array $sortMap = [ // ];
通过这种方法,您可以确定哪些查询字段用于排序,将确定模型字段用于排序。 示例:
protected array $sortMap = [ 'status' => 'status_id' ];
在这个例子中,在传递给构建器的参数中,status 字段在排序键中指定。多亏了这个映射,构建器明白在这种情况下它应该使用模型的 status_id 字段进行排序。
实际应用
要获取过滤、排序、分页的集合,您只需要创建所需构建器的实例,传递一个包含参数的数组,然后应用所需的这些方法。
示例
$query = new ModelQueryBuilder($params); $result = $query ->setFilters() ->setSort() ->setPagination() ->getCollection();
您还可以使用构建器界面来创建您服务中的变体。
$query = new ModelQueryBuilder($params); $collection = $service->getModels($query);
服务
use Sergyjar\QueryBuilder\Contracts\QueryBuilderInterface; public function getModels(QueryBuilderInterface $queryBuilder): Collection { return = $queryBuilder ->setFilters() ->setSort() ->setPagination() ->getCollection(); }
默认值
1. 默认排序
默认情况下,当添加排序请求(->setSort())时,构建器会搜索参数数组中的字段 'sort' 以获取排序字段和 'order' 以获取方向。
如果参数数组中找不到具有这些键的元素,则使用默认值。这些默认值,以及字段和排序方向键,可以在 /config/query-builder.php 中找到并覆盖。
'sort_key' => 'sort', 'order_key' => 'order', 'sort_default' => 'id', 'order_default' => 'asc',
此外,如果您需要 覆盖 排序字段键或默认值,您可以在您的 ModelQueryBuilder 中覆盖它们。构建器将主要关注您的类,然后才是配置。
注意:为了获取正确的排序方向值,您可以使用内置的可能排序枚举 SortDirection。
示例
namespace App\Path\For\File; use App\Models\Model; use Sergyjar\QueryBuilder\AbstractQueryBuilder; use Sergyjar\QueryBuilder\Enums\SortDirection class ModelQueryBuilder extends AbstractQueryBuilder { protected string $sortKey = 'customSortKey'; protected string $orderKey = 'customOrderKey'; protected string $sortDefault = 'custom_sort_model_field'; protected string $orderDefault = SortDirection::DESC; ...
2. 默认分页
默认情况下,当添加分页请求(->setPagination())时,构造函数会在参数数组中查找字段 'page' 以获取请求的页码,以及 'per_page' 以获取每页所需的记录数。
如果参数数组中找不到具有这些键的元素,则使用默认值。这些默认值,以及页码和每页元素数键,可以在 /config/query-builder.php 中找到并覆盖。
'page' => 'page', 'per_page' => 'perPage', 'page_default' => 1, 'per_page_default' => 20,
此外,如果您需要 覆盖 分页字段键或默认值,您可以在 ModelQueryBuilder 中覆盖它们。设计器将首先关注您的类,然后才是配置。
示例
namespace App\Path\For\File; use App\Models\Model; use Sergyjar\QueryBuilder\AbstractQueryBuilder; class ModelQueryBuilder extends AbstractQueryBuilder { protected string $pageKey = 'customPageKey'; protected string $perPageKey = 'customPerPageKey'; protected int $pageDefault = 2; protected int $perPageDefault = 3; ...
附加功能
除了构建器的基本工作方法外,还有一些其他功能,在构建查询时可能很有用。
- 包括已删除项
默认情况下,构建器不考虑软删除的记录,但如果您也想接收此类记录,您可以在请求中添加 withTrashed 修改器。
$query->withTrashed()
重要:如果您在请求中使用 分页 和 withTrashed,则 withTrashed 修改器必须 在 分页之前!否则您将获得 不正确 的分页值。
- 选择
您可以选择查询将返回的模型记录字段。为此,只需将 ->setSelect() 修改器添加到您的请求中,并将要检索的键的数组作为参数传递。
$query->setSelect($select)
- 获取分页
通常您需要将分页数组添加到响应中,以便进一步处理记录列表。通过调用查询修改器 ->getPagination(); 可以轻松完成此操作,此方法将返回一个包含分页字段值的 数组。
$pagination = $query->getPagination();
返回示例
[ 'page' => 20, 'perPage' => 1, 'total' => 12, 'totalPages' => 15, ]