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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2192242/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 04:35:15  来源:igfitidea点击:

What is lazy loading in Hibernate?

javahibernateormlazy-loading

提问by rocker

What is lazy loading in Java? I don't understand the process. Can anybody help me to understand the process of lazy loading?

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

回答by Thomas L?tzer

Say you have a parent and that parent has a collection of children. Hibernate now can "lazy-load" the children, which means that it does not actually load all the children when loading the parent. Instead, it loads them when requested to do so. You can either request this explicitly or, and this is far more common, hibernate will load them automatically when you try to access a child.

假设您有一个父级,并且该父级有一组子级。Hibernate 现在可以“延迟加载”子级,这意味着在加载父级时它实际上并没有加载所有子级。相反,它会在请求时加载它们。你可以明确地请求这个,或者,这是更常见的,当你尝试访问一个孩子时,hibernate 会自动加载它们。

Lazy-loading can help improve the performance significantly since often you won't need the children and so they will not be loaded.

延迟加载可以帮助显着提高性能,因为通常您不需要孩子,因此它们不会被加载。

Also beware of the n+1-problem. Hibernate will not actually load all children when you access the collection. Instead, it will load each child individually. When iterating over the collection, this causes a query for every child. In order to avoid this, you can trick hibernate into loading all children simultaneously, e.g. by calling parent.getChildren().size().

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

回答by Steffen

Lazy Loading? Well, it simply means that child records are not fetched immediately, but automatically as soon as you try to access them.

懒加载?嗯,这只是意味着不会立即获取子记录,而是在您尝试访问它们时自动获取。

回答by Diego Dias

Lazy loading is a design pattern commonly used in computer programming to defer initialization of an object until the point at which it is needed. It can contribute to efficiency in the program's operation if properly and appropriately used

延迟加载是计算机编程中常用的一种设计模式,用于将对象的初始化推迟到需要的时候。如果使用得当和适当,它可以提高程序运行的效率

Wikipedia

维基百科

Link of Lazy Loadingfrom hibernate.org

来自 hibernate.org的延迟加载链接

回答by BalusC

"Lazy loading" means that an entity will be loaded onlywhen you actuallyaccesses the entity for the firsttime.

“延迟加载”是指只有在您一次实际访问该实体时才会加载该实体。

The patternis like this:

模式是这样的:

public Entity getEntity() {
    if (entity == null) {
        entity = loadEntity();
    }
    return entity;
}

This saves the cost of preloading/prefilling allthe entities in a large dataset beforehand while you after all actually don't need allof them.

这节省了预先在大型数据集中预加载/预填充所有实体的成本,而您实际上并不需要所有实体。

In Hibernate, you can configure to lazily load a collection of child entities. The actuallazy loading is then done inside the methods of the PersistentSetwhich Hibernate uses "under the hoods" to assign the collection of entities as Set.

在 Hibernate 中,您可以配置为延迟加载子实体的集合。在实际的延迟加载,然后在方法内部完成PersistentSet这Hibernate使用的“罩下的”指定实体的集合Set

E.g.

例如

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();
}

回答by Pascal Thivent

Martin Fowler defines the Lazy Loadpattern in Patterns of Enterprise Application Architectureas such:

Martin Fowler在Patterns of Enterprise Application Architecture 中定义了延迟加载模式,如下所示:

An object that doesn't contain all of the data you need but knows how to get it.

不包含您需要的所有数据但知道如何获取它的对象。

So, when loading a given object, the idea is to not eager loadthe related object(s) that you may not use immediately to save the related performance cost. Instead, the related object(s) will be loaded only when used.

因此,在加载给定对象时,我们的想法是不要急切加载您可能不会立即使用的相关对象,以节省相关的性能成本。相反,相关对象将仅在使用时加载。

This is not a pattern specific to data access and Hibernate but it is particularly useful in such fields and Hibernate supports lazy loading of one-to-many associations and single-point associations (one-to-one and many-to-one) also under certain conditions. Lazy interaction is discussed in more detail in Chapter 19of the Hibernate 3.0 Reference Documentation.

这不是特定于数据访问和 Hibernate 的模式,但它在这些领域特别有用,而且 Hibernate 还支持一对多关联和单点关联(一对一和多对一)的延迟加载在一定条件下。在 Hibernate 3.0 参考文档的第 19 章中更详细地讨论了惰性交互。

回答by abburi

Hiberante supports the feature of lazy initialization for both entities and collections. Hibernate engine loads only those objects that we are querying for does not other entites or collections.

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

lazy="false" by default loading initialization mention for the only child is lazy.in case of true that is parent is loading does not support child

懒惰=“假”默认加载初始化提到唯一的孩子是懒惰的。如果是真的,父母正在加载不支持孩子

回答by Siva Chimpiri

Lazy setting decides whether to load child objects while loading the Parent Object.You need to do this setting respective hibernate mapping file of the parent class.Lazy = true (means not to load child)By default the lazy loading of the child objects is true. This make sure that the child objects are not loaded unless they are explicitly invoked in the application by calling getChild() method on parent.In this case hibernate issues a fresh database call to load the child when getChild() is actully called on the Parent object.But in some cases you do need to load the child objects when parent is loaded. Just make the lazy=false and hibernate will load the child when parent is loaded from the database.Exampleslazy=true (default)Address child of User class can be made lazy if it is not required frequently.lazy=falseBut you may need to load the Author object for Book parent whenever you deal with the book for online bookshop.

Lazy设置决定在加载Parent Object时是否加载子对象。需要在父类各自的hibernate映射文件中进行此项设置。Lazy = true(表示不加载子对象)默认子对象的延迟加载为true . 这确保除非在应用程序中通过调用父对象上的 getChild() 方法显式调用它们,否则不会加载子对象。对象。但在某些情况下,您确实需要在加载父对象时加载子对象。只需设置lazy=false,hibernate 就会在从数据库加载父级时加载子级。示例lazy=true (默认)如果不经常需要,可以将User 类的地址子级设置为惰性。

回答by Manikandan Adhimoolam

Lazy setting decides whether to load child objects while loading the Parent Object.You need to do this setting respective hibernate mapping file of the parent class.Lazy = true (means not to load child)By default the lazy loading of the child objects is true.

Lazy设置决定在加载Parent Object时是否加载子对象。需要在父类各自的hibernate映射文件中进行此项设置。Lazy = true(表示不加载子对象)默认子对象的延迟加载为true .

回答by Chandresh Solanki

Bydefault lazy loading is true.Lazy loading means when the select query is executed it will not hit the database. It will wait for getter function i.e when we required then ,it will fetch from the datbase. for example: You are a parent who has a kid with a lot of toys. But the current issue is whenever you call him (we assume you have a boy), he comes to you with all his toys as well. Now this is an issue since you do not want him carrying around his toys all the time. So being the rationale parent, you go right ahead and define the toys of the child as LAZY. Now whenever you call him, he just comes to you without his toys.

默认情况下,延迟加载为 true。延迟加载意味着执行选择查询时不会命中数据库。它将等待 getter 函数,即当我们需要时,它将从数据库中获取。例如:您是一位有很多玩具的孩子的父母。但当前的问题是,无论何时你给他打电话(我们假设你有一个男孩),他也会带着他所有的玩具来找你。现在这是一个问题,因为你不希望他一直带着他的玩具。因此,作为合理的父母,您可以直接将孩子的玩具定义为 LAZY。现在每当你给他打电话时,他都会来找你,没有他的玩具。

回答by Bhavin Shah

Lazy fetching decides whether to load child objects while loading the Parent Object. You need to do this setting respective hibernate mapping file of the parent class. Lazy = true(means not to load child) By default the lazy loading of the child objects is true.

Lazy fetching 决定是否在加载父对象的同时加载子对象。您需要对父类的相应休眠映射文件进行此设置。 Lazy = true(意味着不加载子对象)默认情况下,子对象的延迟加载为 true。

This make sure that the child objects are not loaded unless they are explicitly invoked in the application by calling getChild()method on parent.In this case hibernate issues a fresh database call to load the child when getChild()is actully called on the Parent object.

这确保除非在应用程序中通过调用父对象的getChild()方法显式调用子对象,否则不会加载子对象。在这种情况下,当getChild()在父对象上实际调用时,休眠会发出一个新的数据库调用来加载子对象。

But in some cases you do need to load the child objects when parent is loaded. Just make the lazy=false and hibernate will load the child when parent is loaded from the database.

但在某些情况下,您确实需要在加载父对象时加载子对象。只需使 lazy=false 和休眠将在从数据库加载父级时加载子级。

Example : If you have a TABLE ? EMPLOYEE mapped to Employee object and contains set of Address objects. Parent Class : Employee class, Child class : Address Class

示例:如果您有一个 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; 
} 
} 

In the Employee.hbm.xml file

在 Employee.hbm.xml 文件中

<set name="address" inverse="true" cascade="delete" lazy="false"> 
<key column="a_id" /> 
<one-to-many class="beans Address"/> 
</set> 

In the above configuration. If lazy="false": - when you load the Employee object that time child object Address is also loaded and set to setAddresss() method. If you call employee.getAdress() then loaded data returns.No fresh database call.

在上面的配置中。如果lazy="false": - 当您加载 Employee 对象时,子对象 Address 也被加载并设置为 setAddresss() 方法。如果您调用employee.getAdress() 然后加载的数据返回。没有新的数据库调用。

If lazy="true":- This the default configuration. If you don?t mention then hibernate consider lazy=true. when you load the Employee object that time child object Adress is not loaded. You need extra call to data base to get address objects. If you call employee.getAdress()then that time database query fires and return results. Fresh database call.

如果lazy="true":- 这是默认配置。如果你不提到然后休眠考虑lazy=true。当您加载 Employee 对象时,未加载子对象 Adress。您需要额外调用数据库来获取地址对象。如果您调用,employee.getAdress()那么那时数据库查询将触发并返回结果。新的数据库调用。