bugloos / query-sorting-bundle
查询排序包允许您对QueryBuilder和数据库中的数据进行排序。您可以在同一时间对多个列进行排序,也可以在查询构建器中对具有两层深度的关联字段进行排序,而不需要任何连接。
Requires
- php: >=8.1
- doctrine/annotations: ^2.0
- doctrine/doctrine-bundle: ^2.2
- doctrine/orm: ^2.8
- psr/cache: ^1.0 | ^2.0 | ^3.0
- symfony/framework-bundle: ^4.4 | ^5.4 | ^6.0
- symfony/http-kernel: ^4.4 | ^5.4 | ^6.0
- symfony/orm-pack: ^2.2
Requires (Dev)
- ext-json: *
- friendsofphp/php-cs-fixer: ^3.8
- matthiasnoback/symfony-dependency-injection-test: ^4.1
- phpunit/phpunit: ^9.5
- roave/security-advisories: dev-latest
- squizlabs/php_codesniffer: 3.*
- symfony/browser-kit: ^5.4
- symfony/http-client: ^5.4
- zenstruck/foundry: ^1.16
README
它做什么? :)
查询排序包允许您对QueryBuilder和数据库中的数据进行排序。您可以在同一时间对多个列进行排序,也可以在查询构建器中对具有两层深度的关联字段进行排序,而不需要任何连接。安装
composer require bugloos/query-sorting-bundle
兼容性
- PHP v8.1 或更高版本
- Symfony v4.4 或更高版本
用法
假设我们的数据库有以下表和以下关系现在我们想按排序显示图书实体
我们想按价格列对图书实体进行排序,因此我们可以通过查询字符串发送排序数据或使用如下数组内联
/* * 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() ;
贡献

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