【问题标题】:How to fetch entities without their association mapping in Doctrine 2如何在 Doctrine 2 中获取没有关联映射的实体
【发布时间】:2016-01-15 13:17:21
【问题描述】:

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

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

SitePage->SiteMatrix->SiteItems->SiteItemPrices.

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

我的问题是,每次我在我的网站上获得一个页面列表时,学说都会遍历整个关联映射树并返回整个数据库,这非常慢。有时我只想通过 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?

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

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

【问题讨论】:

  • Doctrine 默认应该延迟加载关联。听起来您的所有关联都设置为急切加载。您能否添加两个实体及其关联映射的代码以排除任何关联问题?
  • 感谢您的回复,但这个问题已经存在一年多了。事实证明,我正在使用序列化程序将我的实体序列化为数组,并且正是这个序列化程序调用了关联映射树下的每个 getter 函数。一旦我了解了 JMS 序列化程序包中的排除、最大深度和组功能,一切就变得清晰起来,我能够以更多的控制权使用关联。

标签: php symfony doctrine-orm doctrine


【解决方案1】:

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 章节。

【讨论】:

  • 非常感谢您彻底解释这个概念。使用 JMSSerializer 排除策略使学说关联映射成为一个非常强大的工具。参考的官方文档 - jmsyst.com/libs/serializer/master/cookbook/exclusion_strategies
  • 不客气,感谢您的耐心等待。如果您对 maxDeprh 有更好的解释,请随时告诉我,我会改进我的。
  • 这一切都很好,但这仍然会影响底层查询吗?这是演示,查询仍然需要发生对吗?
  • 如果我排除了关联实体,它是否会影响对 db 的实际查询?
  • 我无法确定从查询端会发生什么,因为我没有深入了解 JMS 序列化程序代码。我的猜测是处理是在查询之后完成的,所以它根本不会影响它,但我又不确定。
猜你喜欢
  • 2016-05-10
  • 1970-01-01
  • 1970-01-01
  • 2018-09-19
  • 2013-03-24
  • 1970-01-01
  • 2015-12-23
  • 2016-01-26
  • 2013-04-03
相关资源
最近更新 更多