具有多对多关系的 Symfony 实体存储库
Symfony entity repository with many-to-many relationship
我有两个实体 product
和 document
,它们通过 many-to-many
关系与 JOIN
table 相关。我的产品实体如下所示,我的文档实体目前没有对产品的引用。
/**
* @ORM\Entity
* @ORM\Table(name="product")
* @ORM\Entity(repositoryClass="\MyApp\CmsBundle\Repository\ProductRepository")
*/
class Product
{
// ...
/**
* @ManyToMany(targetEntity="Document")
* @JoinTable(name="products_documents",
* joinColumns={@JoinColumn(name="product_id", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="document_id", referencedColumnName="id")}
* )
**/
protected $documents;
// ...
public function __construct()
{
$this->documents = new ArrayCollection();
}
public function addDocument(Document $document)
{
$this->documents[] = $document;
return $this;
}
public function removeDocument(Document $document)
{
$this->documents->removeElement($document);
}
public function getDocuments()
{
return $this->documents;
}
当我在网站前端展示产品时,我还会列出它的文档。但是我需要能够根据它们的属性 status
和 privacy
.
过滤掉它们
所以我一直在尝试创建一个实体存储库来处理这个逻辑,但到目前为止我尝试的一切都失败了。我需要实现的是与此类似的查询,但采用 Symfony/Doctrine 格式:
SELECT d.*
FROM documents d, products_documents pd,
WHERE pd.product_id = :product_id
AND pd.document_id = d.id,
AND d.status = 'PUBLISHED',
AND d.privacy = 'PUBLIC';
理想情况下,我希望能够从我的控制器上做一些像这样简单的事情:
// get documents to display on front-end
$documents = $em->getRepository('MyAppCmsBundle:Product')->getDocumentsForProduct($product);
我已经调用了函数,只是不知道如何检索我想要的数据。
更新
这就是我到目前为止所得到的,同时维护工作代码,而不是 returning 文档它 return 所有产品。我不确定如何添加条件以将其指定到我传入的产品,或者 return 文档而不是产品。
ProductRepository.php
public function getDocumentsForProduct(Product $product, $authenticated = false)
{
$query = $this->createQueryBuilder('p')
->join('MyApp\CmsBundle\Entity\Document', 'd')
->where('d.status = :status')
->andWhere('d.privacy = :privacy')
->setParameters(array(
'status' => 'PUBLISHED',
'privacy' => 'PUBLIC',
))
->getQuery();
return $query->getResult();
}
如果你想要它到 return 文档,你应该把它放在你的 DocumentRepository 中。
'createQueryBuilder' 方法自动选择属于存储库类型的实体。所以在你的情况下,这是产品。如果将相同的代码放在 DocumentRepository 中,您应该会得到 Document 实体。
我不知道是否可以使用 QueryBuilder 来更改此设置。但是您可以像这样使用 DQL:
$this->getEntityManager()->createQuery('SELECT p FROM YourBundle:Document WHERE ...');
我有两个实体 product
和 document
,它们通过 many-to-many
关系与 JOIN
table 相关。我的产品实体如下所示,我的文档实体目前没有对产品的引用。
/**
* @ORM\Entity
* @ORM\Table(name="product")
* @ORM\Entity(repositoryClass="\MyApp\CmsBundle\Repository\ProductRepository")
*/
class Product
{
// ...
/**
* @ManyToMany(targetEntity="Document")
* @JoinTable(name="products_documents",
* joinColumns={@JoinColumn(name="product_id", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="document_id", referencedColumnName="id")}
* )
**/
protected $documents;
// ...
public function __construct()
{
$this->documents = new ArrayCollection();
}
public function addDocument(Document $document)
{
$this->documents[] = $document;
return $this;
}
public function removeDocument(Document $document)
{
$this->documents->removeElement($document);
}
public function getDocuments()
{
return $this->documents;
}
当我在网站前端展示产品时,我还会列出它的文档。但是我需要能够根据它们的属性 status
和 privacy
.
所以我一直在尝试创建一个实体存储库来处理这个逻辑,但到目前为止我尝试的一切都失败了。我需要实现的是与此类似的查询,但采用 Symfony/Doctrine 格式:
SELECT d.*
FROM documents d, products_documents pd,
WHERE pd.product_id = :product_id
AND pd.document_id = d.id,
AND d.status = 'PUBLISHED',
AND d.privacy = 'PUBLIC';
理想情况下,我希望能够从我的控制器上做一些像这样简单的事情:
// get documents to display on front-end
$documents = $em->getRepository('MyAppCmsBundle:Product')->getDocumentsForProduct($product);
我已经调用了函数,只是不知道如何检索我想要的数据。
更新
这就是我到目前为止所得到的,同时维护工作代码,而不是 returning 文档它 return 所有产品。我不确定如何添加条件以将其指定到我传入的产品,或者 return 文档而不是产品。
ProductRepository.php
public function getDocumentsForProduct(Product $product, $authenticated = false)
{
$query = $this->createQueryBuilder('p')
->join('MyApp\CmsBundle\Entity\Document', 'd')
->where('d.status = :status')
->andWhere('d.privacy = :privacy')
->setParameters(array(
'status' => 'PUBLISHED',
'privacy' => 'PUBLIC',
))
->getQuery();
return $query->getResult();
}
如果你想要它到 return 文档,你应该把它放在你的 DocumentRepository 中。
'createQueryBuilder' 方法自动选择属于存储库类型的实体。所以在你的情况下,这是产品。如果将相同的代码放在 DocumentRepository 中,您应该会得到 Document 实体。
我不知道是否可以使用 QueryBuilder 来更改此设置。但是您可以像这样使用 DQL:
$this->getEntityManager()->createQuery('SELECT p FROM YourBundle:Document WHERE ...');