【问题标题】:Doctrine many repository for same entity同一实体的多个存储库的学说
【发布时间】:2012-03-08 11:14:57
【问题描述】:

同一实体可以有两个存储库吗?

我尝试了类似的方法,但它不起作用..

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

有什么想法吗?

【问题讨论】:

    标签: doctrine repository entity


    【解决方案1】:

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

    其次,回答您的问题。您可以拥有任意多个使用相同实体的存储库,毕竟它们只是简单的类。

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

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

    【讨论】:

    • 感谢您的回答。我需要它,因为我有一个实际上代表两个类的实体。我没有找到如何用继承解决这个问题。这是这里解释的另一个问题:stackoverflow.com/questions/9501755/…
    • 我实际上想知道,对于管理相同实体的特定于管理方法和操作的存储库,以及特定于前端方法和操作的存储库。太糟糕了,没有办法根据访问路径来规定可以使用哪个存储库。
    • “但是没有什么可以阻止您创建自己的类,这些类执行一些查询并直接、显式地调用它们,而不依赖于 EntityManagers 存储库映射。”你有这样做的例子吗?
    【解决方案2】:

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

    1. “@Repository 注释”可用于指向默认存储库或只是避免它。
    2. 创建通常的repository class,例如“我的实体存储库”。
    3. 在代码中:

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

    【讨论】:

      【解决方案3】:

      我找到了解决方案。 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. 使用特征

      以下示例:

      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的用例。

      【讨论】:

      • 从 trait 层面引用 $this->getEntityManager()->createNativeQuery() 又如何呢?您的 IDE 将不知道 EM。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-19
      • 2016-07-06
      • 2013-10-11
      • 2021-10-06
      相关资源
      最近更新 更多