在hibernate中启动懒加载的方式有那些。
最好能有一种方法能直接在我们的dao中调用该方法后会是的该次查询为懒加载。
不知道有没有这样的方法。不一定说一定是hibernate内置的方法。其他框架。
或者是大牛自己写的方法也可以。
谢谢,大家。。分数就这些了全给了。。

解决方案 »

  1.   

    http://blog.csdn.net/chenwc_csu/archive/2008/07/02/2606392.aspx
       1. 所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。可以提高程序的性能。  
       2.   
       3. 延迟加载一般有三种类型:  
       4.   
       5. 1. 实体对象的延迟加载:  
       6.   
       7. 在×.hbm.xml文件中的配置如下:  
       8.   
       9. <hibernate-mapping>  
      10. <class name=”com.neusoft.entity.User” table=”user” lazy=”true”>  
      11.     ……  
      12. </class>  
      13. </hibernate-mapping>  
      14.   
      15. 通过将class的lazy属性设置为true,来开启延迟加载特性。  
      16.   
      17. 调用代码如下:  
      18.   
      19. User user=(User)session.load(User.class,”1”); (1)  
      20. System.out.println(user.getName());(2)  
      21.   
      22. 当程序运行到(1)的时候,Hibernate并没有查询相应的数据,只有当程序执行到(2)的时候,hibernate才会发起数据库查询操作。  
      23. hibernate是通过中间代理对象来实现延迟加载的,因为session.load() 返回的是一个实体对象的代理类,这里所返回的就是User对象的代理类。代理类中包含目标对象的所有属性和方法,并且属性值被赋值为空,当执行getname() 方法的时候,实际上是通过调用代理对象的getname方法来得到值,然后代理对象再去查询数据库。  
      24. <pre name="code" class="csharp">2. 集合类型的延迟加载  
      25.   
      26. 。hbm。xml的配置如下;  
      27.   
      28. <hibernate-mapping>  
      29.     <class name=”com.neusoft.entity.User” table=”user”>  
      30. …..  
      31. <set name=”addresses” table=”address” lazy=”true” inverse=”true”>  
      32. <key column=”user_id”/>  
      33. <one-to-many class=”com.neusoft.entity.Arrderss”/>  
      34. </set>  
      35.     </class>  
      36. </hibernate-mapping>  
      37.   
      38. 通过将<set>元素的 lazy属性设置为true来开启集合类型的延迟加载特性。我们看下面的代码:  
      39.   
      40. User user=(User)session.load(User.class,”1”);  
      41. Collection addset=user.getAddresses();       (1)  
      42. Iterator it=addset.iterator();                (2)  
      43. while(it.hasNext()){  
      44. Address address=(Address)it.next();  
      45. System.out.println(address.getAddress());  
      46. }  
      47.   
      48. 当程序执行到(1)处时,这时并不会发起对关联数据的查询来加载关联数据,只有运行到(2)处时,真正的数据读取操作才会开始,这时Hibernate会根据缓存中符合条件的数据索引,来查找符合条件的实体对象。  
      49. 在Hibernate中对集合类型进行缓存时,是分两部分进行缓存的,首先缓存集合中所有实体的id列表,然后缓存实体对象,这些实体对象的id列表,就是所谓的数据索引。当查找数据索引时,如果没有找到对应的数据索引,这时就会一条select SQL的执行,获得符合条件的数据,并构造实体对象集合和数据索引,然后返回实体对象的集合,并且将实体对象和数据索引纳入Hibernate的缓存之中。另一方面,如果找到对应的数据索引,则从数据索引中取出id列表,然后根据id在缓存中查找对应的实体,如果找到就从缓存中返回,如果没有找到,在发起 select SQL查询。在这里我们看出了另外一个问题,这个问题可能会对性能产生影响,这就是集合类型的缓存策略。如果我们如下配置集合类型:  
      50.   
      51. <hibernate-mapping>  
      52.     <class name=”com.neusoft.entity.User” table=”user”>  
      53. …..  
      54. <set name=”addresses” table=”address” lazy=”true” inverse=”true”>  
      55. <cache usage=”read-only”/><span style="font-family: Arial,Verdana,Sans-Serif;">  
      56. </span><key column=”user_id”/></pre>  所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。可以提高程序的性能。延迟加载一般有三种类型:1. 实体对象的延迟加载:在×.hbm.xml文件中的配置如下:<hibernate-mapping>
    <class name=”com.neusoft.entity.User” table=”user” lazy=”true”>
        ……
    </class>
    </hibernate-mapping>通过将class的lazy属性设置为true,来开启延迟加载特性。调用代码如下:User user=(User)session.load(User.class,”1”);(1)
    System.out.println(user.getName());(2)当程序运行到(1)的时候,Hibernate并没有查询相应的数据,只有当程序执行到(2)的时候,hibernate才会发起数据库查询操作。
    hibernate是通过中间代理对象来实现延迟加载的,因为session.load() 返回的是一个实体对象的代理类,这里所返回的就是User对象的代理类。代理类中包含目标对象的所有属性和方法,并且属性值被赋值为空,当执行getname() 方法的时候,实际上是通过调用代理对象的getname方法来得到值,然后代理对象再去查询数据库。
    view plaincopy to clipboardprint?   1. 2. 集合类型的延迟加载  
       2.   
       3. 。hbm。xml的配置如下;  
       4.   
       5. <hibernate-mapping>  
       6.     <class name=”com.neusoft.entity.User” table=”user”>  
       7. …..  
       8. <set name=”addresses” table=”address” lazy=”true” inverse=”true”>  
       9. <key column=”user_id”/>  
      10. <one-to-many class=”com.neusoft.entity.Arrderss”/>  
      11. </set>  
      12.     </class>  
      13. </hibernate-mapping>  
      14.   
      15. 通过将<set>元素的lazy属性设置为true来开启集合类型的延迟加载特性。我们看下面的代码:  
      16.   
      17. User user=(User)session.load(User.class,”1”);  
      18. Collection addset=user.getAddresses();       (1)  
      19. Iterator it=addset.iterator();                (2)  
      20. while(it.hasNext()){  
      21. Address address=(Address)it.next();  
      22. System.out.println(address.getAddress());  
      23. }  
      24.   
      25. 当程序执行到(1)处时,这时并不会发起对关联数据的查询来加载关联数据,只有运行到(2)处时,真正的数据读取操作才会开始,这时Hibernate会根据缓存中符合条件的数据索引,来查找符合条件的实体对象。  
      26. 在Hibernate中对集合类型进行缓存时,是分两部分进行缓存的,首先缓存集合中所有实体的id列表,然后缓存实体对象,这些实体对象的id列表,就是所谓的数据索引。当查找数据索引时,如果没有找到对应的数据索引,这时就会一条select SQL的执行,获得符合条件的数据,并构造实体对象集合和数据索引,然后返回实体对象的集合,并且将实体对象和数据索引纳入Hibernate的缓存之中。另一方面,如果找到对应的数据索引,则从数据索引中取出id列表,然后根据id在缓存中查找对应的实体,如果找到就从缓存中返回,如果没有找到,在发起select SQL查询。在这里我们看出了另外一个问题,这个问题可能会对性能产生影响,这就是集合类型的缓存策略。如果我们如下配置集合类型:  
      27.   
      28. <hibernate-mapping>  
      29.     <class name=”com.neusoft.entity.User” table=”user”>  
      30. …..  
      31. <set name=”addresses” table=”address” lazy=”true” inverse=”true”>  
      32. <cache usage=”read-only”/><span style="font-family: Arial,Verdana,Sans-Serif;">  
      33. </span><key column=”user_id”/>  2. 集合类型的延迟加载。hbm。xml的配置如下;<hibernate-mapping>
        <class name=”com.neusoft.entity.User” table=”user”>
    …..
    <set name=”addresses” table=”address” lazy=”true” inverse=”true”>
    <key column=”user_id”/>
    <one-to-many class=”com.neusoft.entity.Arrderss”/>
    </set>
        </class>
    </hibernate-mapping>通过将<set>元素的lazy属性设置为true来开启集合类型的延迟加载特性。我们看下面的代码:User user=(User)session.load(User.class,”1”);
    Collection addset=user.getAddresses();       (1)
    Iterator it=addset.iterator();                (2)
    while(it.hasNext()){
    Address address=(Address)it.next();
    System.out.println(address.getAddress());
    }当程序执行到(1)处时,这时并不会发起对关联数据的查询来加载关联数据,只有运行到(2)处时,真正的数据读取操作才会开始,这时Hibernate会根据缓存中符合条件的数据索引,来查找符合条件的实体对象。
    在Hibernate中对集合类型进行缓存时,是分两部分进行缓存的,首先缓存集合中所有实体的id列表,然后缓存实体对象,这些实体对象的id列表,就是所谓的数据索引。当查找数据索引时,如果没有找到对应的数据索引,这时就会一条select SQL的执行,获得符合条件的数据,并构造实体对象集合和数据索引,然后返回实体对象的集合,并且将实体对象和数据索引纳入Hibernate的缓存之中。另一方面,如果找到对应的数据索引,则从数据索引中取出id列表,然后根据id在缓存中查找对应的实体,如果找到就从缓存中返回,如果没有找到,在发起select SQL查询。在这里我们看出了另外一个问题,这个问题可能会对性能产生影响,这就是集合类型的缓存策略。如果我们如下配置集合类型:<hibernate-mapping>
        <class name=”com.neusoft.entity.User” table=”user”>
    …..
    <set name=”addresses” table=”address” lazy=”true” inverse=”true”>
    <cache usage=”read-only”/>
    <key column=”user_id”/>view plaincopy to clipboardprint?   1. <pre name="code" class="csharp"><one-to-many class=”com.neusoft.entity.Arrderss”/>  
       2. </set>  
       3.     </class>  
       4. </hibernate-mapping>  
       5.   
       6. 这里我们应用了<cache usage=”read-only”/>配置,如果采用这种策略来配置集合类型,Hibernate将只会对数据索引进行缓存,而不会对集合中的实体对象进行缓存。如上配置我们运行下面的代码:  
       7.   
       8. User user=(User)session.load(User.class,”1”);  
       9. Collection addset=user.getAddresses();        
      10. Iterator it=addset.iterator();                 
      11. while(it.hasNext()){  
      12. Address address=(Address)it.next();  
      13. System.out.println(address.getAddress());  
      14. }  
      15. System.out.println(“Second query……”);  
      16. User user2=(User)session.load(User.class,”1”);  
      17. Collection it2=user2.getAddresses();  
      18. while(it2.hasNext()){  
      19. Address address2=(Address)it2.next();  
      20. System.out.println(address2.getAddress());  
      21. }  
      22.   
      23. 运行这段代码,会得到类似下面的输出:  
      24. Select * from user where id=’1’;  
      25. Select * from address where user_id=’1’;  
      26. Tianjin  
      27. Dalian  
      28. Second query……  
      29. Select * from address where id=’1’;  
      30. Select * from address where id=’2’;  
      31. Tianjin  
      32. Dalian  
      33.   
      34. 我们看到,当第二次执行查询时,执行了两条对address表的查询操作,为什么会这样?这是因为当第一次加载实体后,根据集合类型缓存策略的配置,只对集合数据索引进行了缓存,而并没有对集合中的实体对象进行缓存,所以在第二次再次加载实体时,Hibernate找到了对应实体的数据索引,但是根据数据索引,却无法在缓存中找到对应的实体,所以 Hibernate根据找到的数据索引发起了两条select SQL的查询操作,这里造成了对性能的浪费,怎样才能避免这种情况呢?我们必须对集合类型中的实体也指定缓存策略,所以我们要如下对集合类型进行配置:  
      35.   
      36. <hibernate-mapping>  
      37.     <class name=”com.neusoft.entity.User” table=”user”>  
      38. …..  
      39. <set name=”addresses” table=”address” lazy=”true” inverse=”true”>  
      40. <cache usage=”read-write”/>  
      41. <key column=”user_id”/>  
      42. <one-to-many class=”com.neusoft.entity.Arrderss”/>  
      43. </set>  
      44.     </class>  
      45. </hibernate-mapping>  
      46. 此时Hibernate会对集合类型中的实体也进行缓存,如果根据这个配置再次运行上面的代码,将会得到类似如下的输出:  
      47. Select * from user where id=’1’;  
      48. Select * from address where user_id=’1’;  
      49. Tianjin  
      50. Dalian  
      51. Second query……  
      52. Tianjin  
      53. Dalian  
      54. 这时将不会再有根据数据索引进行查询的SQL语句,因为此时可以直接从缓存中获得集合类型中存放的实体对象。</pre>  
      55.   
      56.   
      57. <pre class="java" name="code">3. 属性的延迟加载  
      58.   
      59. 如下配置我们的实体类:  
      60.   
      61.   
      62.   
      63. <hibernate-mapping>  
      64.   
      65. <class name=”com.neusoft.entity.User” table=”user”>  
      66.   
      67. ……  
      68.   
      69. <property name=”resume” type=”java.sql.Clob” column=”resume” lazy=”true”/>  
      70.   
      71.     </class>  
      72.   
      73. </hibernate-mapping>  
      74.   
      75. 通过对<property>元素的lazy属性设置true来开启属性的延迟加载,  
      76.   
      77. 根据上面的配置,执行代码如下:  
      78.   
      79. String sql=”from User user where user.name=’zx’ ”;  
      80.   
      81. Query query=session.createQuery(sql);    (1)  
      82.   
      83. List list=query.list();  
      84.   
      85. for(int i=0;i<list.size();i++){  
      86.   
      87. User user=(User)list.get(i);  
      88.   
      89. System.out.println(user.getName());  
      90.   
      91. System.out.println(user.getResume());    (2)  
      92.   
      93. }  
      94.   
      95.   
      96.   
      97. 当执行到(1)处时,会生成类似如下的 SQL语句:  
      98.   
      99.   
     100.   
     101. Select id,age,name from user where name=’zx’;  
     102.   
     103.   
     104.   
     105. 这时Hibernate会检索User实体中所有非延迟加载属性对应的字段数据,当执行到(2)处时,会生成类似如下的SQL 语句:  
     106.   
     107.   
     108.   
     109. Select resume from user where id=’1’;  
     110.   
     111.   
     112.   
     113. 这时会发起对resume字段数据真正的读取操作。</pre>