roc*_*ker 170 java orm hibernate lazy-loading
什么是Java中的延迟加载?我不明白这个过程.任何人都可以帮我理解延迟加载的过程吗?
Tho*_*zer 262
假设您有父母,并且该父母有一个孩子的集合.Hibernate现在可以"延迟加载"子进程,这意味着它在加载父进程时实际上并没有加载所有子进程.相反,它会在请求时加载它们.你可以明确地请求它,或者这更常见,当你试图访问一个孩子时,hibernate会自动加载它们.
延迟加载可以帮助显着提高性能,因为通常您不需要孩子,因此不会加载它们.
还要注意n + 1问题.当您访问集合时,Hibernate实际上不会加载所有子节点.相反,它将单独加载每个孩子.迭代集合时,会导致查询每个子集.为了避免这种情况,您可以通过调用parent.getChildren().size()来欺骗hibernate同时加载所有子节点.
Bal*_*usC 72
"延迟加载"表示只有在您第一次实际访问实体时才会加载实体.
该模式是这样的:
public Entity getEntity() {
if (entity == null) {
entity = loadEntity();
}
return entity;
}
Run Code Online (Sandbox Code Playgroud)
这样可以节省预先加载/预填充大型数据集中所有实体的成本,而您实际上并不需要全部实体.
在Hibernate中,您可以配置为延迟加载子实体的集合.在实际的延迟加载随后的方法内部完成PersistentSet这Hibernate使用"下罩"指定实体的集合Set.
例如
public class Parent {
private Set<Child> children;
public Set<Child> getChildren() {
return children;
}
}
Run Code Online (Sandbox Code Playgroud)
.
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();
}
Run Code Online (Sandbox Code Playgroud)
小智 15
默认延迟加载是真的.延迟加载意味着当执行选择查询时它不会命中数据库.它将等待getter函数,即当我们需要时,它将从数据库中获取.例如:你是一个有很多玩具的孩子的父母.但是当前的问题是每当你打电话给他时(我们假设你有一个男孩),他也带着他所有的玩具来找你.现在这是一个问题,因为你不希望他一直带着他的玩具.因此,作为理性的父母,你要向前走,并将孩子的玩具定义为LAZY.现在每当你打电话给他时,他就会在没有玩具的情况下来找你.
Bha*_*hah 11
延迟提取决定在加载父对象时是否加载子对象.您需要这样设置父类的相应hibernate映射文件.
Lazy = true(表示不加载子)默认情况下,子对象的延迟加载为true.
这样可以确保不加载子对象,除非通过getChild()在parent上调用方法在应用程序中显式调用它们.在这种情况下,hibernate会getChild()在父对象上执行动作时发出新的数据库调用来加载子对象.
但在某些情况下,您需要在加载父项时加载子对象.只需使lazy = false,hibernate将在从数据库加载父级时加载子级.
示例:如果您有一个TABLE?EMPLOYEE映射到Employee对象并包含一组Address对象.父类:Employee类,子类:地址类
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;
}
}
Run Code Online (Sandbox Code Playgroud)
在Employee.hbm.xml文件中
<set name="address" inverse="true" cascade="delete" lazy="false">
<key column="a_id" />
<one-to-many class="beans Address"/>
</set>
Run Code Online (Sandbox Code Playgroud)
在上面的配置中.如果lazy="false": - 当您加载Employee对象时,也会加载时间子对象Address并将其设置为setAddresss()方法.如果你调用employee.getAdress()然后加载数据返回.没有新的数据库调用.
如果lazy="true": - 这是默认配置.如果你不提,那么hibernate认为lazy = true.当您加载Employee对象时,未加载时间子对象Adress.您需要额外调用数据库才能获取地址对象.如果您调用employee.getAdress()那时数据库查询将触发并返回结果.新鲜数据库调用.
小智 9
用外行的语言来说,就像你正在做蛋糕一样,你需要冰箱里的5-10种食材.您有两种选择,从冰箱中取出所有食材并将其放在厨房平台上,或在需要时带上您想要的食物.
类似地,在急切加载中,您获取有关bean及其相关类的所有信息(不是子项或is-a关系,但有关系,即蛋糕有面粉,有牛奶,有奶油等),并且在延迟加载的情况下,首先你只带来来自同一张桌子的标识符和价值(必要的成分,如果蛋糕,你需要先放在你的碗里).来自其他表的所有信息将在需要/使用时获取.
延迟加载允许您推迟关联检索或更好地控制获取策略。
当您使用 EAGER 加载时,您定义了一个无法在查询时覆盖的全局获取计划,这意味着您仅限于在设计实体模型时做出的决定。该EAGER抓取是一个代码味道,因为抓取策略是查询时策略,它可能从一个业务用例的不同而异。
该抓取策略是一个非常重要的方面,因为太多EAGER取会导致严重的性能相关的问题。