如何在Doctrine 2

时间:2016-01-15 13:17:21

标签: php symfony doctrine-orm doctrine

如果在Doctrine中有一组关联映射实体,有时您可能希望检索这些实体而不提取其映射的关联并减慢查询速度。

例如,我有一组实体,它们是链接数据库表链中的关联映射。它们都是OnetoMany协会,并作为产品页面矩阵中价格的层次结构。它们可以表示为:

SitePage->SiteMatrix->SiteItems->SiteItemPrices.

关联映射工作正常,当我使用findBy方法获取根SitePage对象时,它包含表示链中映射实体的数组。换句话说,SitePage对象包含所有矩阵,其中包含包含所有价格的所有项目。到目前为止一切都很好。

我的问题是,每当我在我的网站上获得一个页面列表时,doctrine就会遍历整个关联映射树并返回整个数据库,这非常慢。有时我想通过ID获取我的SitePage实体,而不包含所有映射的关联。

我已经研究了懒惰和额外的延迟加载关联,但它们似乎只影响某些函数,而不是findBy等。官方文档远非有用: http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/tutorials/extra-lazy-associations.html

Stack Overflow上的其他类似问题尚未得到解答: Doctrine 2 Association Mapping Overhead?

是否有一种简单的方法来获取没有映射关联的实体?我目前看到的最简单的方法是为每个数据库表创建两个实体,一个具有关联映射,另一个不需要在需要它们的单独情况下使用。对我来说,你不能简单地获取一个实体并指定是否要将其链接到其他实体或单独获取它,这似乎很奇怪。

感谢您提供有关此主题的任何信息。

1 个答案:

答案 0 :(得分:2)

JMSSerializer排除策略可以帮助您。

首先,默认情况下排除所有属性:

// ...

use JMS\Serializer\Annotation as JMS;

/**
 * @ORM\Entity
 * @JMS\ExclusionPolicy("all")
 */
class Foo

然后,选择排除或公开您的属性:

/**
 * @ORM\Column(type="string")
 * @JMS\Expose
 */
protected $name;

此外,对于您的关联,您可以使用MaxDepth来限制结果的关联条目。示例:

// Entity
/** @MaxDepth(1) */
private $selfAssociatedEntries;

// Controller
use JMS\Serializer\SerializationContext;

$serializer->serialize($data, 'json', SerializationContext::create()->enableMaxDepthChecks());

像这样,您的实体将包含$selfAssociatedEntries序列化,但$selfAssociatedEntries不具有$selfAssociationEntries属性。
序列化仅限于第一个父对象。

Groups是一项功能强大的功能,可让您公开某些操作的属性并将其排除在另一个操作之外:

/**
 * @ORM\Column(type="string", length=255, nullable=true, unique=false)
 * @JMS\Groups({"default"}) // Set the group to expose the property
 */
protected $name;

在控制器中,设置用于序列化的组:

// Property 'name' is exposed
$serializer->serialize($data, 'json', SerializationContext::create()->setGroups(array('default')));

有关更多信息,请查看文档的Exclusion Strategies章节。