快速业务通道

容器的延迟初始(Lazy Initialization) - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-20

容器的延迟初始(Lazy Initialization)

时间:2011-01-27 javaworld

有时候您只是想要获得物件中某个属性的资料,如果您的物件中包括Set等容器物件,若从资料库中载入资料时全部载入所有的物件,却只是为了取得某个属性,显然的这样很没有效率。

以Set中的范例来说,如果您只是想取得物件之後,显示物件的某些属性,例如name属性:

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属性来设定是否使用延迟初始,例如在映射文件中如下设定:

User.hbm.xml <?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>

由於lazy属性被设定为false,延迟初始的功能被关闭,所以上面的程式会使用以下的SQL来查询:

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

容器的延迟初始(Lazy Initialization)(2)

时间:2011-01-27 javaworld

在开启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不能关闭,如果关闭会丢出LazyInitializationException 例外,例如下面的程式就会丢出例外:

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.getEmails()); // 先载入容器中的物件 session.close(); Iterator iterator = user.getEmails().iterator(); while(iterator.hasNext()) {    System.out.println(iterator.next()); }

即使启用延迟初始,在Hibernate.initialize()该行,email容器中的物件已经被载入,所以即使关闭session也无所谓了,这种情况发生在某个情况下,您启用了延迟初始,而使用者操作过程中,会在稍後一阵子才用到email容器,您不能浪费session在这段时间的等待上,所以您先行载入容器物件,直接关闭session以节省资源。

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号