Session session = sessionFactory.openSession(); User user = (User) session.load(User.class, new Integer(1)); System.out.println(user.getName()); session.close();在这个例子中,email的信息不必要从数据库中全部加载,在Hibernate中支持容器的延迟初始(Lazy onitialization),只有在真正需要容器对象中的数据时,才从数据库中取得数据,预设容器类会使用延迟加载的功能,例如上面的程序实际上会使 用以下的SQL:
Hibernate: select user0_.id as id0_, user0_.name as name0_0_ from user user0_ where user0_.id=?可以藉由映像文件中的lazy属性来设定是否使用延迟初始,例如在映射文件中如下设定:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="onlyfun.caterpillar.User" table="user">
....
<set name="emails" table="email" lazy="false">
<key column="id"/>
<element type="java.lang.String"
column="address"/>
</set>
</class>
</hibernate-mapping>
Hibernate: select user0_.id as id0_, user0_.name as name0_0_ from user user0_ where user0_.id=? Hibernate: select emails0_.id as id0_, emails0_.address as address0_ from email emails0_ where emails0_.id=?所有的容器对象之数据一并被查询了,即使程序中还不会使用到容器中的对象信息。
Session session = sessionFactory.openSession(); User user = (User) session.load(User.class, new Integer(1)); System.out.println(user.getName()); Iterator iterator = user.getEmails().iterator(); while(iterator.hasNext()) { System.out.println(iterator.next()); } session.close();在开启SQL显示的情况下,会显示以下的内容:
Hibernate: select user0_.id as id0_, user0_.name as name0_0_ from user user0_ where user0_.id=? caterpillar Hibernate: select emails0_.id as id0_, emails0_.address as address0_ from email emails0_ where emails0_.id=? caterpillar.onlyfun@yahoo.com caterpillar.onlyfun@gmail.com |
Session session = sessionFactory.openSession(); User user = (User) session.load(User.class, new Integer(1)); System.out.println(user.getName()); session.close(); Iterator iterator = user.getEmails().iterator(); while(iterator.hasNext()) { System.out.println(iterator.next()); }如果您使用了延迟初始,而在某些时候仍有需要在session关闭之后取得相关对象,则可以使用Hibernate.initialize()来先行加载相关对象,例如:
Session session = sessionFactory.openSession(); User user = (User) session.load(User.class, new Integer(1)); System.out.println(user.getName()); Hibernate.initialize(user); // 先加载容器中的对象 session.close(); Iterator iterator = user.getEmails().iterator(); while(iterator.hasNext()) { System.out.println(iterator.next()); }即使启用延迟初始,在Hibernate.initialize()该行,email容器中的对象已经被加载,所以即使关闭session也无所谓了,这 种情况发生在某个情况下,您启用了延迟初始,而使用者操作过程中,会在稍后一阵子才用到email容器,您不能浪费session在这段时间的等待上,所 以您先行加载容器对象,直接关闭session以节省资源。