Java Hibernate中的延迟加载是什么?

Java Hibernate中的延迟加载是什么?,java,hibernate,orm,lazy-loading,Java,Hibernate,Orm,Lazy Loading,Java中的延迟加载是什么?我不明白这个过程。有谁能帮助我理解延迟加载的过程吗?假设您有一位家长,并且该家长有一组孩子。Hibernate现在可以“延迟加载”子对象,这意味着在加载父对象时它实际上不会加载所有子对象。相反,它会在请求时加载它们。您可以显式地请求,或者,更常见的是,当您尝试访问子对象时,hibernate将自动加载它们 延迟加载有助于显著提高性能,因为您通常不需要子级,因此不会加载它们 还要注意n+1问题。当您访问集合时,Hibernate实际上不会加载所有子项。相反,它将分别加载

Java中的延迟加载是什么?我不明白这个过程。有谁能帮助我理解延迟加载的过程吗?

假设您有一位家长,并且该家长有一组孩子。Hibernate现在可以“延迟加载”子对象,这意味着在加载父对象时它实际上不会加载所有子对象。相反,它会在请求时加载它们。您可以显式地请求,或者,更常见的是,当您尝试访问子对象时,hibernate将自动加载它们

延迟加载有助于显著提高性能,因为您通常不需要子级,因此不会加载它们


还要注意n+1问题。当您访问集合时,Hibernate实际上不会加载所有子项。相反,它将分别加载每个子级。在集合上迭代时,这会导致对每个子级进行查询。为了避免这种情况,您可以欺骗hibernate同时加载所有子级,例如调用parent.getChildren().size()。

延迟加载?好吧,这仅仅意味着子记录不会立即获取,而是在您尝试访问它们时自动获取

延迟加载是一种设计模式 常用于计算机编程 延迟对象的初始化 直到需要的时候。 它有助于提高工作效率 程序运行是否正常,以及 适当使用

维基百科

来自hibernate.org的链接“延迟加载”意味着只有当您实际第一次访问实体时才会加载该实体

问题是这样的:

public Entity getEntity() {
    if (entity == null) {
        entity = loadEntity();
    }
    return entity;
}
这节省了预先预加载/预填充大型数据集中所有实体的成本,而实际上并不需要所有实体

在Hibernate中,您可以配置为延迟加载子实体的集合。然后,实际的延迟加载在Hibernate使用的方法中完成,Hibernate使用“在引擎罩下”将实体集合分配为
Set

例如

公共类父类{
私人儿童;
公共集getChildren(){
返回儿童;
}
}

public void doSomething(){
Set children=parent.getChildren();//仍然不包含任何内容。
//无论何时,只要您(间接地)调用以下内容之一,
//Hibernate将开始实际加载并填充集合。
儿童。尺寸();
children.iterator();
}
Martin Fowler将模式定义为:

一个对象,它不包含您需要的所有数据,但知道如何获取这些数据

因此,在加载给定对象时,不要急于加载可能不会立即使用的相关对象,以节省相关的性能成本。相反,只有在使用时才会加载相关对象

这不是特定于数据访问和Hibernate的模式,但它在此类字段中特别有用,并且Hibernate还支持在特定条件下延迟加载一对多关联和单点关联(一对一和多对一)。
Hibernate 3.0参考文档的第1部分将更详细地讨论惰性交互

Hibernate支持实体和集合的延迟初始化功能。 Hibernate引擎只加载我们正在查询的对象,而不加载其他实体或集合


lazy=“false”默认情况下,为唯一的子对象加载初始化选项为lazy。如果为true,则“正在加载的父对象”不支持“子对象”

lazy设置决定在加载父对象时是否加载子对象。您需要对父类的各个hibernate映射文件执行此设置。lazy=true(表示不加载子对象)默认情况下,子对象的延迟加载为true。这确保不会加载子对象,除非通过调用父对象上的getChild()方法在应用程序中显式调用它们。在这种情况下,hibernate会在getChild()时发出一个新的数据库调用来加载子对象在父对象上实际调用。但在某些情况下,在加载父对象时确实需要加载子对象。只需将lazy设置为false,hibernate将在从数据库加载父对象时加载子对象。Exampleslazy=true(默认)如果不经常需要,则可以将用户类的Address子对象设置为lazy。lazy=False,但无论何时处理在线书店的书籍,您都可能需要为Book parent加载Author对象。

lazy设置决定在加载父对象时是否加载子对象。您需要分别在hibernate映射文件中执行此设置父类的e。Lazy=true(表示不加载子对象)默认情况下,子对象的延迟加载为true。

默认情况下,延迟加载为true。延迟加载表示当执行select查询时,它不会命中数据库。它将等待getter函数,即当我们需要时,它将从数据库中获取。 例如: 你是一个有很多玩具的孩子的父母。但是现在的问题是,无论你什么时候打电话给他(我们假设你有一个男孩),他也会带着他的玩具来找你。现在这是一个问题,因为你不希望他一直带着他的玩具。
因此,作为基本原理的家长,您可以直接将孩子的玩具定义为懒惰。现在,无论您何时呼叫他,他都会不带玩具来找您。

懒惰抓取决定在加载父对象时是否加载子对象。 您需要分别设置父类的hibernate映射文件。
Lazy=true
(表示不加载子对象) 默认情况下,子对象的延迟加载为true

这确保不会加载子对象,除非通过调用父对象上的
getChild()
方法在应用程序中显式调用它们。在这种情况下,hibernate会发出一个新的数据库调用来加载子对象
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();
}
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; 
} 
} 
<set name="address" inverse="true" cascade="delete" lazy="false"> 
<key column="a_id" /> 
<one-to-many class="beans Address"/> 
</set>