gpt4 book ai didi

Symfony - 如何访问实体的存储库

转载 作者:行者123 更新时间:2023-12-04 02:07:12 25 4
gpt4 key购买 nike

有几种方法可以访问 Symfony2 Controller 或服务中的实体存储库,每种方法都有其优点和缺点。首先我在这里列出它们,然后询问是否有更好的解决方案,或者这些是我们唯一的选择,我们应该根据自己的喜好选择一个或一些。我还想知道方法 5(我最近开始使用它)是否很好,并且不会违反任何规则或有任何副作用。

基本方法:在 Controller 中使用实体管理器或将其注入(inject)服务,然后访问我想要的任何存储库。这是在 Controller 或服务中访问存储库的基本方式。

class DummyController
{
public function dummyAction($id)
{
$em = $this->getDoctrine()->getManager();
$em->getRepository('ProductBundle:Product')->loadProduct($id);
}
}

但是这种方法存在一些问题。第一个问题是我不能按 Ctrl + 单击例如 loadProduct 函数并直接进入它的实现(除非有一种我不知道的方法)。另一个问题是我最终会一遍又一遍地重复这部分代码。

方法二:另一种方法是在我的服务或 Controller 中定义一个 getter 来访问我的存储库。
class DummyService
{
protected $em;

public function __construct(EntityManager $em)
{
$this->em = $em;
}

public function dummyFunction($id)
{
$this->getProductRepository()->loadProduct($id);
}

/**
* @return \ProductBundle\Entity\Repository\ProductRepository
*/
public function getProductRepository()
{
return $this->em->getRepository('ProductBundle:Product');
}
}

这种方法解决了第一个问题,不知何故解决了第二个问题,但我仍然有
在我的服务或 Controller 中重复我需要的所有 setter/getter ,我的服务和 Controller 中也会有几个 setter/getter ,只是为了访问存储库

方法三:另一种方法是将存储库注入(inject)我的服务,这很好,特别是如果我们对代码有很好的控制并且我们不参与将整个容器注入(inject)您的服务的其他开发人员。
class DummyService
{
protected $productRepository;

public function __construct(ProductRepository $productRepository)
{
$this->productRepository = $productRepository;
}

public function dummyFunction($id)
{
$this->productRepository->loadProduct($id);
}
}

这种方法解决了第一个和第二个问题,但是如果我的服务很大
它需要处理很多存储库,那么这不是一个好主意
向我的服务注入(inject)例如 10 个存储库。

方法四:另一种方法是有一个服务来包装我的所有存储库并将此服务注入(inject)其他服务。
class DummyService
{
protected $repositoryService;

public function __construct(RepositoryService $repositoryService)
{
$this->repositoryService = $repositoryService;
}

public function dummyFunction($id)
{
$this->repositoryService->getProductRepository()->loadProduct($id);
}
}

存储库服务:
class RepositoryService
{
protected $em;

public function __construct(EntityManager $em)
{
$this->em = $em;
}

/**
* @return \ProductBundle\Entity\Repository\ProductRepository
*/
public function getProductRepository()
{
return $this->em->getRepository('ProductBundle:Product');
}

/**
* @return \CmsBundle\Entity\Repository\PageRepository
*/
public function getPageRepository()
{
return $this->em->getRepository('CmsBundle:Page');
}
}

这种方法也解决了第一个和第二个问题。但是当我们拥有例如 200 个实体时,RepositoryService 会变得如此之大。

方法五:最后,我可以在每个返回其存储库的实体中定义一个静态方法。
class DummyService
{
protected $em;

public function __construct(EntityManager $em)
{
$this->em = $em;
}

public function dummyFunction($id)
{
Product::getRepository($this->em)->loadProduct($id);
}
}

我的实体:
/**
* Product
*
* @ORM\Table(name="saman_product")
* @ORM\Entity(repositoryClass="ProductBundle\Entity\ProductRepository")
*/
class Product
{
/**
*
* @param \Doctrine\ORM\EntityManagerInterface $em
* @return \ProductBundle\Entity\ProductRepository
*/
public static function getRepository(EntityManagerInterface $em)
{
return $em->getRepository(__CLASS__);
}
}

这种方法解决了第一个和第二个问题,我也不需要定义一个
访问存储库的服务。我最近使用过它,到目前为止它对我来说是最好的方法。我不认为这种方法会破坏实体的规则,因为它是在类范围内定义的,也是你的。但我仍然不确定它是否有任何副作用。

最佳答案

在 Doctrine 世界中,实体只是应该是 getter 和 setter(以及添加或删除)的贫血模型,因此注入(inject)存储库将是错误的做法。

这完全取决于您希望与 Doctrine 的耦合程度。如果您可以通过 @doctrine服务然后你可以使用类似的东西:

$this->repository = $doctrine->getRepository('CmsBundle:Page');

.. 但是,如前所述,这将要求您通过 @doctrine服务到每一个对象。这意味着,如果您出于某种原因决定不使用 Doctrine,您将需要重构所有代码以适应您的新方法(无论可能是什么),但这对您来说可能不是问题。此外,存储库将被类型提示,因此无法保证(除了检查它是否是代码中的正确类)来保证它是正确的服务。

在我看来,最干净的方法是创建一个服务,例如:

XML
<service id="cms.page_repository"
class="Acme\CmsBundle\Repository\PageRepository">
<factory service="doctrine" method="getRepository" />
<argument>AcmeDemoBundle:ExampleRepository</argument>
</service>

YAML
cms.page_repository:
class: Acme\CmsBundle\Repository\PageRepository
factory: [ @doctrine, 'getRepository' ]

.. 然后您可以将您的存储库服务传递到您想要的任何地方,而无需在您的实际代码中使用 Doctrine 服务。使用这种方法,如果您决定放弃 Doctrine,您只需要更改服务定义而不需要重构所有内容。此外,由于您正在创建特定存储库的服务,您可以在 __construct 中使用类型提示。确保注入(inject)正确的服务,例如:
public function __construct(PageRepository $repository)
{
$this->repository = $repository;
}

关于Symfony - 如何访问实体的存储库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31955745/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com