bugloos/query-sorting-bundle

查询排序包允许您对QueryBuilder和数据库中的数据进行排序。您可以在同一时间对多个列进行排序,也可以在查询构建器中对具有两层深度的关联字段进行排序,而不需要任何连接。

安装次数: 4,405

依赖项: 0

建议者: 0

安全: 0

星标: 13

关注者: 2

分支: 1

开放问题: 0

类型:symfony-bundle

v1.1.1 2023-08-06 16:00 UTC

This package is auto-updated.

Last update: 2024-09-06 18:20:22 UTC


README

Scrutinizer Code Quality GitHub Workflow Status Code Intelligence Status

它做什么? :)

查询排序包允许您对QueryBuilder和数据库中的数据进行排序。您可以在同一时间对多个列进行排序,也可以在查询构建器中对具有两层深度的关联字段进行排序,而不需要任何连接。

安装

composer require bugloos/query-sorting-bundle

兼容性

  • PHP v8.1 或更高版本
  • Symfony v4.4 或更高版本

用法

假设我们的数据库有以下表和以下关系

Service running preview

现在我们想按排序显示图书实体

我们想按价格列对图书实体进行排序,因此我们可以通过查询字符串发送排序数据或使用如下数组内联

/*
 * Sort book by price ascending
*/
//Get api/book/index?order[price]=ASC
OR
$orders = [
    'price' => SortType::ASC,
];

/*
 * Sort book by price descending
*/
//Get api/book/index?order[price]=DESC
OR
$orders = [
    'price' => SortType::DESC,
];

您只需在控制器中添加排序类并调用排序方法

use Bugloos\QuerySortingBundle\Service\QuerySorting;

以下代码位于Book控制器中。

如您所见,首先应调用for()方法并将QueryBuilder作为参数传递给该方法

然后调用parameters()方法并传递排序请求项

最后,应调用sort()方法以执行排序

sort()方法的返回值是QueryBuilder,因此您可以在排序后向QueryBuilder添加任何其他内容。
public function index(
    Request $request,
    BookRepository $bookRepository,
    QuerySorting $querySorting
): Response {
    $queryBuilder = $bookRepository->createQueryBuilder('b');
    
    $queryBuilder = $querySorting->for($queryBuilder)
        ->parameters($request->get('order'))
        ->sort()
    ;
    
    return $queryBuilder->getQuery()->getResult();
}

如果您想对ManyToOne关联字段或一级深度关联进行排序,则应添加映射器。

要添加映射器,请调用addMapper()方法添加单个映射器或调用mappers()方法使用数组发送多个映射器

addMapper()方法的第一参数是参数名称,第二参数是关系名称及其字段名称,字段名称由" . "符号分隔

$mappers = [
    'country' => 'country.name',
];

例如,我们想按国家名称对图书实体进行排序。图书与国家实体具有ManyToOne关系

/*
 * Sort book by Country name ascending
*/
//Get api/book/index?order[country]=ASC
OR
$orders = [
    'country' => SortType::ASC,
];

/*
 * Sort book by Country name descending
*/
//Get api/book/index?order[country]=DESC
OR
$orders = [
    'country' => SortType::DESC,
];

以下代码位于Book控制器中。

public function index(
    Request $request,
    BookRepository $bookRepository,
    QuerySorting $querySorting
): Response {
    $queryBuilder = $bookRepository->createQueryBuilder('b');
    
    $queryBuilder = $querySorting->for($queryBuilder)
        ->parameters($request->get('order'))
        ->addMapper('country', 'country.name')
        ->sort()
    ;
    
    return $queryBuilder->getQuery()->getResult();
}

注意:不需要在QueryBuilder中添加您的关联连接,因为如果不添加连接,我会自动添加。 ;)

$queryBuilder = $bookRepository->createQueryBuilder('b');

OR

$queryBuilder = $bookRepository->createQueryBuilder('b')
    ->addSelect('country')   
    ->leftJoin('b.country', 'country')      
;

如果您想对ManyToMany关联字段或两层深度关联进行排序,则应再次添加映射器

$mapper = [
    'age' => 'bookUsers.user.age',
];

例如,我们想按作者年龄对图书实体进行排序。图书与用户实体具有ManyToMany关系

/*
 * Sort book by Writer age ascending
*/
//Get api/book/index?order[age]=ASC
OR
$orders = [
    'age' => SortType::ASC,
];

/*
 * Sort book by Writer age descending
*/
//Get api/book/index?order[age]=DESC
OR
$orders = [
    'age' => SortType::DESC,
];

以下代码位于Book控制器中。

public function index(
    Request $request,
    BookRepository $bookRepository,
    QuerySorting $querySorting
): Response {
    $queryBuilder = $bookRepository->createQueryBuilder('b');
    
    $queryBuilder = $querySorting->for($queryBuilder)
        ->parameters($request->get('order'))
        ->addMapper('age', 'bookUsers.user.age')
        ->sort()
    ;
    
    return $queryBuilder->getQuery()->getResult();
}

注意:您还可以使用多个列进行排序,只需发送多个排序数据查询字符串即可

/*
 * Sort book by title ascending and price descending
*/
//Get api/book/index?order[title]=ASC&order[price]=DESC
OR
$orders = [
    'title' => SortType::ASC,
    'price' => SortType::DESC,
];

建议

您可以通过配置文件更改两个参数,只需在config/packages/目录中创建yaml文件,然后您可以更改查询的默认缓存时间和默认关系分隔符如下

query_sorting:
  default_cache_time: 3600
  separator: '.'

注意:您可以为每个查询单独设置缓存时间,如果您没有设置任何缓存时间,则使用配置文件中的默认缓存时间

$queryBuilder = $querySorting->for($queryBuilder)
    ->parameters($request->get('order'))
    ->cacheTime(120)
    ->sort()
;

贡献 v beer

如果你发现了一个问题,或者有更好的方法来做某事,请随时提交一个问题或拉取请求。