学说中 fetch="EAGER" 和 fetch="LAZY" 有啥区别

Posted

技术标签:

【中文标题】学说中 fetch="EAGER" 和 fetch="LAZY" 有啥区别【英文标题】:What is the difference between fetch="EAGER" and fetch="LAZY" in doctrine学说中 fetch="EAGER" 和 fetch="LAZY" 有什么区别 【发布时间】:2015-01-09 13:57:44 【问题描述】:

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

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

/**
 * @ManyToOne(targetEntity="Cart", cascade="all", fetch="LAZY")
 */

【问题讨论】:

【参考方案1】:

简单来说,当你加载一个实体时,如果它与一个或多个实体有关联,那么学说应该怎么做?

如果关联被标记为EAGER,它也会获取并加载关联的实体。

如果关联被标记为 LAZY,则学说将创建代理对象(虚拟对象)来代替实际实体。只有当您第一次调用该关联实体(如$cart->getItems())时,教义才会从数据库中获取并加载该对象。 (这是default Behaviour)

参考:https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/advanced-configuration.html#association-proxies

【讨论】:

顺便说一句。默认行为是什么?我假设它是LAZY? 我认为延迟加载是教义的默认设置:doctrine-orm.readthedocs.io/en/latest/tutorials/… 我从不写的时候默认是什么 来自“Calamity Jane”的链接不再有效,这是一个更新的链接(适用于 2.6):doctrine-project.org/projects/doctrine-orm/en/2.6/tutorials/…。从链接中引用默认行为:Associations are marked as Lazy by default, which means the whole collection object for an association is populated the first time its accessed. @famas23 LAZY 可能更快,但这仅取决于您的需要。如果您从不使用这些相关部件,那么它肯定会更快,因为保湿工作要做的工作更少。否则,如果您知道您将实际使用相关部件,那么立即加载它们是有意义的。【参考方案2】:

关于它们之间区别的附加信息:

(fetch = "EAGER")

一旦从学说中加载原始查询目标实体,就会获取相关实体。这意味着在 DB 上没有额外的 SQL 查询。

(fetch = "LAZY")

仅当原始查询目标实体调用引用方法(例如$cart->getItems())时,才会获取关联实体。也就是说,DB 上有additional SQL 查询。

【讨论】:

谢谢。我来到这里想知道在获取目标时急切获取是否会导致额外的查询。 迄今为止最好的解释

以上是关于学说中 fetch="EAGER" 和 fetch="LAZY" 有啥区别的主要内容,如果未能解决你的问题,请参考以下文章

JPA 2.1 Eager Fetch 属性

Grails eager fetch 不会检索所有数据

Hibernate EAGER fetch 和 cascade-type all 有啥区别

Fetch Type LAZY 仍然会导致 Eager 加载 Hibernate Spring 数据

[Hibernate] - EAGER and LAZY

使用 JPA 在 Hibernate 中使用 EAGER 类型进行多次提取