Answers:
假设您有一个父母,而那个父母有很多孩子。Hibernate现在可以“延迟加载”子级,这意味着它在加载父级时实际上并没有加载所有子级。而是在要求时加载它们。您可以显式地请求此请求,或者(更常见的是),当您尝试访问孩子时,hibernate会自动加载它们。
延迟加载可以帮助显着提高性能,因为通常不需要子级,因此不会加载它们。
还要提防n + 1问题。当您访问集合时,Hibernate实际上不会加载所有子代。相反,它将单独加载每个孩子。遍历集合时,这将导致每个孩子的查询。为了避免这种情况,您可以诱使休眠模式同时加载所有子级,例如,通过调用parent.getChildren()。size()。
“延迟加载”是指仅当您第一次实际访问实体时,才会加载实体。
该模式是这样的:
public Entity getEntity() {
if (entity == null) {
entity = loadEntity();
}
return entity;
}
这样可以节省预先在大型数据集中预加载/预填充所有实体的成本,而实际上您根本不需要所有实体。
在Hibernate中,您可以配置为延迟加载子实体的集合。在实际的延迟加载,然后在方法内部完成PersistentSet
这Hibernate使用的“罩下的”指定实体的集合Set
。
例如
public class Parent {
private Set<Child> children;
public Set<Child> getChildren() {
return children;
}
}
。
public void doSomething() {
Set<Child> children = parent.getChildren(); // Still contains nothing.
// Whenever you call one of the following (indirectly),
// Hibernate will start to actually load and fill the set.
children.size();
children.iterator();
}
Martin Fowler 在企业应用程序体系结构模式中定义了惰性加载模式,如下所示:
一个不包含您需要的所有数据但知道如何获取它的对象。
因此,在加载给定对象时,其想法是不要急于加载您可能不会立即使用的相关对象以节省相关性能成本。而是仅在使用时加载相关对象。
这不是特定于数据访问和Hibernate的模式,但是在此类领域中特别有用,并且Hibernate还支持延迟加载一对多关联和单点关联(一对一和多对一)。在某些条件下。Hibernate 3.0参考文档的第19章将更详细地讨论惰性交互。
延迟获取决定在加载父对象时是否加载子对象。您需要这样做来设置父类各自的休眠映射文件。
Lazy = true
(意味着不加载子对象)默认情况下,子对象的延迟加载为true。
这样可以确保不加载子对象,除非在应用程序中通过调用getChild()
parent的方法显式调用了子对象。在这种情况下,hibernate会发出一个新的数据库调用,以getChild()
在对Parent对象进行实际调用时加载子对象。
但是在某些情况下,确实需要在加载父对象时加载子对象。只需设置lazy = false,当从数据库中加载父对象时,休眠将加载子对象。
示例:如果您有TABLE?EMPLOYEE映射到Employee对象,并包含一组Address对象。上级:雇员级,下级:地址级
public class Employee {
private Set address = new HashSet(); // contains set of child Address objects
public Set getAddress () {
return address;
}
public void setAddresss(Set address) {
this. address = address;
}
}
在Employee.hbm.xml文件中
<set name="address" inverse="true" cascade="delete" lazy="false">
<key column="a_id" />
<one-to-many class="beans Address"/>
</set>
在以上配置中。如果lazy="false"
:-在加载Employee对象时,该时间子对象Address也将被加载并设置为setAddresss()方法。如果调用employee.getAdress(),则返回加载的数据。没有新的数据库调用。
如果lazy="true"
:-这是默认配置。如果您不提及,则休眠时请考虑lazy = true。当您加载Employee对象时,该时间子对象Adress不会被加载。您需要对数据库进行额外的调用才能获取地址对象。如果您致电,employee.getAdress()
则该时间数据库查询将触发并返回结果。新的数据库调用。
延迟设置决定是否在加载父对象时加载子对象,需要设置父类各自的休眠映射文件。lazy = true(表示不加载子对象)默认情况下,子对象的延迟加载为true 。这样可以确保不加载子对象,除非通过在父对象上调用getChild()方法在应用程序中显式调用了子对象。在这种情况下,当在父对象上实际调用getChild()时,hibernate发出一个新的数据库调用来加载子对象对象。但是在某些情况下,确实需要在加载父对象时加载子对象。只需将lazy = false设置为false,当从数据库中加载父级时,休眠将加载子级。示例lazy = true(默认值)如果不需要经常使用,则可以将User类的地址子级设置为惰性。
延迟加载允许您推迟关联检索或更好地控制获取策略。
使用EAGER加载时,您将定义一个全局获取计划,该计划无法在查询时被覆盖,这意味着您仅限于在设计实体模型时做出的决定。该EAGER抓取是一个代码味道,因为抓取策略是查询时策略,它可能从一个业务用例的不同而异。
该抓取策略是一个非常重要的方面,因为太多EAGER取会导致严重的性能相关的问题。
好吧,这只是意味着加载当前需要的数据,而不是立即加载现在不使用的全部数据。从而使应用程序加载时间比平时更快。
延迟设置决定是否在加载父对象时加载子对象,需要设置父类各自的休眠映射文件。lazy = true(表示不加载子对象)默认情况下,子对象的延迟加载为true 。
令人惊讶的是,没有任何答案谈论在屏幕后休眠的方式是如何实现的。
延迟加载是一种设计模式,出于性能原因,该模式可有效地用于休眠模式,其中涉及以下技术。
1.字节码检测:
使用休眠挂钩增强了基类定义,以拦截对该实体对象的所有调用。
在编译时或运行[加载]时完成
1.1 编译时间
编译后操作
主要由maven / ant插件提供
1.2 运行时间
Hibernate返回的实体对象是实型的代理。