garak / orm-criteria
应用过滤到 Doctrine 查询构建器
v0.1.0
2024-05-06 12:40 UTC
Requires
- php: ^8.1
- doctrine/orm: ^2.7 || ^3.0
Requires (Dev)
- phpunit/phpunit: ^9.6
This package is auto-updated.
Last update: 2024-09-06 13:32:33 UTC
README
这个库旨在简化使用 Doctrine 存储库的过滤。它是 PUGX FilterBundle 的理想伴侣。
设置
运行 composer require garak/orm-criteria
。无需配置。
用法
这个库的基本思想是应用开放/封闭原则(SOLID 中的“O”),以避免每次需要应用新的过滤器时都不得不修改代码。
💡 提示 关于“过滤器”的概念,请参阅上面提到的 FilterBundle
您有两个可用的类:AbstractCriterion
和 Filterer
。将后者注入到您的存储库中,然后您可以开始创建您的标准。
假设您有一个 UserRepository
,并且您想根据以下字段过滤用户:“用户名”、“启用”(是/否)和“国家”。
让我们创建以下类
<?php namespace YourNamespace\Repository\Criteria\User; use Doctrine\ORM\QueryBuilder; use Garak\OrmCriteria\AbstractCriterion; use YourDomain\Entity\User; final class CountryUserCriterion extends AbstractCriterion { protected static string $className = User::class; protected static string $field = 'country'; }
<?php namespace YourNamespace\Repository\Criteria\User; use Doctrine\ORM\QueryBuilder; use Garak\OrmCriteria\AbstractCriterion; use YourDomain\Entity\User; final class EnabledUserCriterion extends AbstractCriterion { protected static string $className = User::class; protected static string $field = 'enabled'; }
<?php namespace YourNamespace\Repository\Criteria\User; use Doctrine\ORM\QueryBuilder; use Garak\OrmCriteria\AbstractCriterion; use YourDomain\Entity\User; final class UsernameUserCriterion extends AbstractCriterion { protected static string $className = User::class; protected static string $field = 'username'; protected static string $compare = self::LIKE; }
然后配置服务
services: _defaults: autowire: true autoconfigure: true # feel fre to use the tag name your prefer _instanceof: Garak\OrmCriteria\AbstractCriterion: tags: ['garak.criterion'] # if you changed the tag name above, be sure that you use the same name here Garak\OrmCriteria\Filterer: bind: $criteria: !tagged_iterator garak.criterion
现在,让我们在您的存储库中使用它
<?php namespace YourNamespace\Repository\UserRepository; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\QueryBuilder; use Garak\OrmCriteria\Filterer; use YourDomain\Entity\User; readonly class UserRepository { public function __construct( private EntityManagerInterface $manager, private Filterer $filterer, ) { }; public function listUsers(array $filters): array { $builder = $this->manager ->createQueryBuilder() ->from(User::class, 'u') ->select('u') ; $this->filterer->filter(User::class, $filters); return $builder->getQuery->execute(); } }
高级用法
您可以将排序选项与过滤器一起传递,如下例所示
$filters['_sort']['field'] = 'username';
$filters['_sort']['direction'] = 'DESC';
如果您的标准需要比基本运算符更复杂的操作,您可以定义一个 filter
方法并添加您的逻辑。示例
<?php namespace YourNamespace\Repository\Criteria\User; use Doctrine\ORM\QueryBuilder; use Garak\OrmCriteria\AbstractCriterion; use YourDomain\Entity\User; final class UnchartedUserCriterion extends AbstractCriterion { protected static string $className = User::class; protected static string $field = 'map'; protected static function filter(QueryBuilder $builder, string $value, string $alias): void { $builder ->andWhere($alias.'.coordinates.latitudine is null') ->andWhere($alias.'.coordinated.longitudine is null') ; } }
您可以使用不同类型的比较运算符,请参阅 Filterer
类中定义的常量。
默认情况下,该库期望找到与过滤字段名称匹配的数据库名称:例如,在上面的代码中,过滤字段 username
期望数据库字段 u.username
。如果不是这种情况,您可以在您的标准类中定义一个静态属性 $dbField
。