Hibernae 的延迟加载是一个非常常用的技术,实体的集合属性默认会被延迟加载,
实体所关联的实体默认也会被延迟加载。Hibernate 通过这种延迟加载来降低系
统的内存开销,从而保证 Hibernate 的运行性能。
下面先来剖析 Hibernate 延迟加载的“秘密”。
集合属性的延迟加载
当 Hibernate 从数据库中初始化某个持久化实体时,该实体的集合属性是否随持
久化类一起初始化呢?如果集合属性里包含十万,甚至百万的记录,在初始化持久
化实体的同时,完成所有集合属性的抓取,将导致性能急剧下降。完全有可能系统
只需要使用持久化类集合属性中的部分记录,而完全不是集合属性的全部,这样,
没有必要一次加载所有的集合属性。
对于集合属性,通常推荐使用延迟加载策略。所谓延迟加载就是等系统需要使用集
合属性时才从数据库装载关联的数据。
例如下面 Person 类持有一个集合属性,该集合属性里的元素的类型为
Address,该 Person 类的代码片段如下:
清单 1. Person.java
public class Person { // 标识属性 private Integer id; // Person 的 name 属性
private String name; // 保留 Person 的 age 属性 private int age; // 使用 Set 来
保存集合属性 private Set
addresses = new HashSet
(); //
下面省略了各属性的
setter
和
getter
方法
... }
为了让 Hibernate 能管理该持久化类的集合属性,程序为该持久化类提供如下映
射文件:
清单 2. Person.hbm.xml
< xml version="1.0" encoding="GBK" >
从上面映射文件的代码可以看出,Person 的集合属性中的 Address 类只是一个
普通的 POJO。该 Address 类里包含 detail、zip 两个属性。由于 Address 类代
码非常简单,故此处不再给出该类的代码。
上面映射文件中 元素里的代码指定了 lazy="true"(对于 元素来说,
lazy="true"是默认值),它指定 Hibernate 会延迟加载集合属性里 Address 对
象。
例如通过如下代码来加载 ID 为 1 的 Person 实体:
Session session = sf.getCurrentSession(); Transaction tx =
session.beginTransaction(); Person p = (Person) session.get(Person.class,
1); //<1> System.out.println(p.getName());