doctrine中fetch="EAGER"和fetch="LAZY"有什么区别?

83

@ManyToOne注释中的fetch="EAGER"fetch="LAZY"有什么区别?

/**
 * @ManyToOne(targetEntity="Cart", cascade={"all"}, fetch="EAGER")
 */

/**
 * @ManyToOne(targetEntity="Cart", cascade={"all"}, fetch="LAZY")
 */
2个回答

121
简单来说,当您加载一个实体并且它与一个或多个实体有关联时,doctrine应该做什么?
如果关联标记为EAGER,它将同时获取和加载相关的实体。
如果关联标记为LAZY,doctrine将创建代理对象(虚拟对象)代替实际实体。只有当您第一次调用该关联实体(例如$cart->getItems())时,doctrine才会从数据库中获取和加载该对象。 (这是默认行为
参考:https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/advanced-configuration.html#association-proxies

顺便问一下,默认行为是什么?我猜应该是“LAZY”吧? - fritzmg
2
在我看来,Doctrine的默认设置是惰性加载:http://doctrine-orm.readthedocs.io/en/latest/tutorials/extra-lazy-associations.html - Calamity Jane
当我从未编写每个时,默认值是什么? - A.Seddighi
2
"Calamity Jane" 的链接已经失效,这里提供一个更新的链接(适用于2.6版本):https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/tutorials/extra-lazy-associations.html#extra-lazy-associations。引用链接中关于默认行为的说明:“关联默认标记为Lazy,这意味着在第一次访问关联时会填充整个集合对象。” - k00ni
懒惰是默认行为,我认为它更快! - famas23
2
@famas23 “懒加载”可能更快,但这取决于你的需求。如果你从未使用过这些关联部分,那么它肯定会更快,因为填充工作量较小。否则,如果你知道自己实际上会使用这些关联部分,那么立即加载它们是有意义的。 - userfuser

40

关于它们之间的区别,以下是额外的信息:

(fetch = "EAGER")

当原始查询目标实体从Doctrine中加载时,相关联的实体将会被立即获取。这意味着没有额外的SQL查询。

(fetch = "LAZY")

只有当原始查询目标实体调用引用方法时,例如$cart->getItems(),相关联的实体才会被获取。这意味着会有额外的SQL查询。


2
谢谢。我来这里想知道当获取目标时,是否会导致额外的查询。 - amacrobert
1
到目前为止最好的解释 - Yes Barry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接