Doctrine为同一个实体的许多存储库

时间:2012-03-08 11:14:58

标签: doctrine repository entity

是否可以为同一个实体提供两个存储库?

我尝试过类似的东西,但它不起作用..

class PackageRepository extends EntityRepository
{
    public function __construct($em, Mapping\ClassMetadata $class)
    {
        $cmf = $em->getMetadataFactory();
        $class = $cmf->getMetadataFor('Product');
        parent::__construct($em, $class);
    }
}

有什么想法吗?

3 个答案:

答案 0 :(得分:5)

首先,你为什么要这样做?

第二,回答你的问题。你可以拥有尽可能多的存储库来处理相同的实体,毕竟它们只是简单的类。

但是您可以使用@Repository注释(或YAML或XML,无论如何)仅将一个类与实体类链接。所有映射数据都存储在EntityManager中。 EntityManager只知道一个存储库类与实体类链接,如果你试图用$entity->getReposiotry()或类似的方法获取它,它将只返回链接的类。

但没有什么可以阻止你创建自己的类来执行某些查询并直接显式地调用它们,而不依赖于EntityManagers存储库映射。

答案 1 :(得分:1)

我找到了解决方案。 PHP中的一些东西称为Trait

示例:

class UserRepository extends EntityRepository {

   public function adminQuery1();
   public function adminQuery2();
   public function adminQuery3();
   public function adminQuery4();
   public function adminQuery5();
   public function adminQuery6();    

   public function frontEndQuery1();
   public function frontEndQuery2(); 
   public function frontEndQuery3(); 
   public function frontEndQuery4(); 
   public function frontEndQuery5(); 
   public function frontEndQuery6();     
}

现在继续使用不同的特定查询部分,您的存储库很快就会变得混乱和太长。 你可以

  1. 创建彼此继承的多个存储库或
  2. 使用特征
  3. 以下示例:

    Trait AdminQuery {
       public function adminQuery1();
       public function adminQuery2();
       public function adminQuery3();
       public function adminQuery4();
       public function adminQuery5();
       public function adminQuery6();    
    }
    
    Trait FrontEndQuery {
       public function adminQuery1();
       public function adminQuery2();
       public function adminQuery3();
       public function adminQuery4();
       public function adminQuery5();
       public function adminQuery6();    
    }
    

    实际的存储库类。

    class UserRepository extends EntityRepository {
       use AdminQuery;
       use FrontEndQuery;      
    }
    

    这样做的好处是,关键字this将引用使用Trait的上下文,这意味着您可以访问EntityRepository的所有功能

    最后找到了Trait的用例。

答案 2 :(得分:1)

当两个Symfony包与同一个实体一起工作时,我也遇到了同样的问题,但每个包的查询都不同,所以我还决定为每个包创建单独的存储库。对于 Doctrine 2 ,解决方案可以是:

  1. " @Repository annotation"可用于指向默认存储库或只是避免它。
  2. 创建常规repository class,例如" MyEntityRepository&#34 ;.
  3. 在代码中:

    $myEntityRepo = new MyEntityRepository($entityManager, $entityManager->getClassMetadata('AppBundle:MyEntity'));