Hibernate延迟加载教程

在任何应用程序中, Hibernate 模式都以急切或惰性模式从数据库读取数据。 Hibernate 延迟加载是指按需延迟加载数据时的策略。

1. Hibernate 延迟加载-我们为什么需要它?

考虑一种常见的Internet Web应用程序:在线商店。商店维护产品目录。在最原始的级别上,可以将其建模为管理一系列产品实体的目录实体。在一家大型商店中,可能有成千上万种产品归为各种重叠类别。

当客户访问商店时,必须从数据库中加载目录。我们可能不希望实现将代表成千上万种产品的每个实体中的每一个加载到内存中。对于足够大的零售商,鉴于机器上可用的物理内存量,这甚至可能是不可能的。

即使这是可能的,也可能会削弱网站的性能。相反,我们只希望加载目录,可能还需要加载类别。仅当用户向下钻取类别时,才应从数据库中加载该类别中的一部分产品。

为了解决这个问题,Hibernate提供了一种称为延迟加载的功能。启用后,仅当直接请求实体的关联实体时,才会加载它们。

2.延迟加载如何解决上述问题

现在,当我们了解了问题之后,让我们了解延迟加载实际上如何在现实生活中提供帮助。如果我们考虑解决上面讨论的问题,那么我们将以以下方式访问类别(或目录):

//Following code loads only a single category from the database:
Category category = (Category)session.get(Category.class,new Integer(42));

但是,如果访问了该类别的所有产品,并且延迟加载有效,则会根据需要从数据库中提取产品。例如,在以下代码段中,将加载关联的产品对象,因为在第二行中已明确引用了该产品。

//Following code loads only a single category from the database
Category category = (Category)session.get(Category.class,new Integer(42));
//This code will fetch all products for category 42 from database - "NOW"
Set<Product> products = category.getProducts();

这解决了我们仅在需要时才加载产品的问题。

3.如何在 Hibernate 模式下启用延迟加载

在进一步进行操作之前,重要的是要重述延迟加载的默认行为,以防使用 Hibernate 映射和注解。

默认行为是“快速加载”属性值和“延迟加载”集合。如果您以前使用过普通的Hibernate 2(映射文件),则默认情况下会急切加载所有引用(包括集合),这与您可能会记得的相反。另请注意,@OneToMany@ManyToMany关联默认为LAZY加载。和@OneToOne@ManyToOne默认为EAGER加载。记住这一点很重要,以避免将来出现任何陷阱。

要显式启用延迟加载,必须在要使用 Hibernate 注解时要延迟加载的关联上使用“ fetch = FetchType.LAZY”

一个hibernare延迟加载示例如下所示:

@OneToMany( mappedBy = "category", fetch = FetchType.LAZY )
private Set<ProductEntity> products;

平行于另一个属性"FetchType.LAZY"就是"FetchType.EAGER"这仅仅是相对的,即LAZY它将加载关联实体以及当所有者实体是取出的第一时间。

4.延迟加载在 Hibernate 状态下如何工作

Hibernate可以将延迟加载行为应用于实体和关联的最简单方法是通过提供它们的代理实现。Hibernate通过替换从实体类派生的代理来拦截对实体的调用。如果缺少所请求的信息,则在将控制权移交给父实体的实现之前,将从数据库中加载该信息。

请注意,当关联表示为集合类时,将创建包装器(本质上是集合的代理,而不是集合所包含的实体),并替换为原始集合。当您访问该集合代理时,您在返回的代理集合中得到的不是代理实体;它是代理实体。而是它们是实际的实体。您无需在理解此概念上施加太大压力,因为在运行时几乎没有关系。

5.延迟加载对分离实体的影响

众所周知,hibernate只能通过会话访问数据库,因此,如果实体与会话分离,并且当我们尝试访问尚未加载的关联(通过代理或集合包装器)时,Hibernate会抛出一个LazyInitializationException

解决方法是确保通过将实体附加到会话来使该实体再次成为持久性,或者确保在将实体从会话中分离之前,将访问所有需要的字段(将它们加载到实体中)。

这就是这个简单但非常重要的概念,即如何在hibernate中加载惰性对象。对于初学者来说,这可能是 Hibernate 获取策略采访问题中的一个问题

如果不清楚或您想讨论任何事情,请发表评论。

学习愉快!

saigon has written 1440 articles

Leave a Reply