sergyjar/laravel-query-builder

一种简单的方法,在考虑过滤、排序和分页的情况下获取模型集合

1.0.3 2024-04-19 16:14 UTC

This package is auto-updated.

Last update: 2024-09-19 17:05:54 UTC


README

在Github上的包 | 在Packagist上的包

一种简单的方法,在考虑过滤、排序和分页的情况下获取模型集合。

注意:此包需要 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,
]