jurjean / spray-persistence-bundle
Requires
Requires (Dev)
- doctrine/data-fixtures: dev-master
- doctrine/doctrine-fixtures-bundle: dev-master
This package is not auto-updated.
Last update: 2024-09-14 12:49:40 UTC
README
一个增强Doctrine2仓库功能的Symfony2包。
简介
此包提供了一种以抽象方式查询对象的方法
$articles->filter('currentlyPublished'); $articles->filter('writtenBy', new Author('Buster')); $articles->filter('ascending');
它有一个通用的API
$articleCount = count($articles); foreach ($articles as $article) { }
允许轻松分页
foreach ($articles->paginate(1) as $article) { }
并且可以独立使用!您不需要symfony,可以将它集成到任何选择的框架中(但是Doctrine是必需的)。
安装
在您的composer.json中要求"jurjean/spray-persistence-bundle"
{ "require": { "jurjean/spray-persistence-bundle": "2.2.*@dev" } }
在您的AppKernel中注册SprayPersistenceBundle
class AppKernel extends Kernel { public function registerBundles() { $bundles = array( // ... new Spray\PersistenceBundle\SprayPersistenceBundle(), ); return $bundles; } }
问题
Doctrine2提供了一个很好的API,允许您通过仓库查询实体。然而,仓库模式并不非常DRY。
如果您想要进行上述描述的查询,您可能会得到一个类似的仓库
class ArticleRepository extends Repository { public function findCurrentlyPublished($order) { } public function findCurrentlyPublishedAndWrittenBy(Author $author, $order) { } }
如您所想象的,添加更多条件的唯一方法是通过复制。这就是RepositoryFilter的作用所在。
实体过滤器
优先级实体过滤器
您可能希望某个过滤器具有优先级。为了做到这一点,您必须实现PrioritizedFilterInterface
use Doctrine\ORM\QueryBuilder; use Spray\PersistenceBundle\EntityFilter\EntityFilterInterface; use Spray\PersistenceBundle\EntityFilter\PrioritizedFilterInterface; class First implements EntityFilterInterface, PrioritizedFilterInterface { public function filter(QueryBuilder $queryBuilder, $options = array()) { } public function getName() { return 'first'; } public function getPriority() { return 100; } } class Last implements EntityFilterInterface, PrioritizedFilterInterface { public function filter(QueryBuilder $queryBuilder, $options = array()) { } public function getName() { return 'last'; } public function getPriority() { return -100; } }
无论您以何种顺序添加这些过滤器,执行顺序仍然是第一个然后是最后一个。
$repository->filter('last'); // Added at priority level -100 $repository->filter('first'); // Added at priority level 100, before 'last'
冲突的实体过滤器
如果您有可能会相互冲突的过滤器(例如,如果它们在相同的列上添加了WHERE语句),您可以实现ConflictingFilterInterface
use Doctrine\ORM\QueryBuilder; use Spray\PersistenceBundle\EntityFilter\ConflictingFilterInterface; class ArticlesConflictingWith implements ConflictingFilterInterface { public function filter(QueryBuilder $queryBuilder, $options = array()) { } public function getName() { return 'conflictingWith'; } public function getConflictingFilters() { return array('another'); } }
如果'repository filter'作用域中存在'another',则在添加ArticlesConflictingWith时将删除它。
$articles->filter('another'); $articles->filter('conflictingWith'); // This is now the only filter
过滤器注册表
过滤器注册表用于向仓库过滤器提供可用的实体过滤器。您可以通过编程方式构建它们,或者创建自己的注册表类。之后,您需要将注册表注入到仓库过滤器中。
class ArticleFilters extends FilterRegistry { public function __construct() { $this->add(new ArticlesPublishedSince()); $this->add(new ArticlesWrittenBy()); } } $articles = new RepositoryFilter($entityManager->getRepository('Article')); $articles->setFilterLocator(new ArticleFilters()); $articles->filter('publishedSince'); $articles->filter('writtenBy', new Author('Buster'));
Symfony集成
您可以通过扩展父级di容器定义spray_persistence.repository_filter并为其提供一个实体名称作为参数,轻松配置您的仓库过滤器。
<container> <services> <service id="bundle.articles" parent="spray_persistence.repository_filter"> <argument>Bundle\Entity\Article</argument> </service> </services> </container>
通过将它们标记为具有名称spray_persistence.entity_filter来添加过滤器。您可以将它们设置为全局(对于所有仓库)或局部(对于单个仓库)。您通过添加repository作为标记选项来使它们局部。
<container> <services> <service id="bundle.articles" parent="spray_persistence.repository_filter"> <argument>Bundle\Entity\Article</argument> </service> <service id="bundle.filter.global" class="Bundle\EntityFilter\Global"> <tag name="spray_persistence.entity_filter" /> </service> <service id="bundle.filter.local" class="Bundle\EntityFilter\Local"> <tag name="spray_persistence.entity_filter" repository="bundle.articles" /> </service> </services> </container>
示例
有关更多示例,请参阅此项目的集成测试。