1. 程式人生 > >hibernate延遲加載

hibernate延遲加載

設置 集合類型 finall sil 調試 以及 狀態 editor 要求

本節內容:

  • l 掌握延遲策略概念
  • l 掌握實體對象的延遲加載
  • l 掌握集合類型的延遲加載
  • l 了解屬性延遲加載

1 延遲策略概念

  • 延遲加載機制是為了避免一些無謂的性能開銷而提出來的,所謂延遲加載就是當在真正需要數據的時候,才真正執行數據加載操作。
  • 在Hibernate中提供了對實體對象的延遲加載以及對集合的延遲加載,另外在Hibernate3中還提供了對屬性的延遲加載。
  • Hibernate中的延遲加載策略只有在session打開的狀態下有效。

2 實體對象延遲加載

如果想對實體對象使用延遲加載,必須要在實體的映射配置文件中進行相應的配置,如下所示:

<!-- class的lazy屬性設為true,則為實體的延遲加載 
--> <class name="com.silvan.pojo.News" table="news" lazy="true"> <id name="id"> <generator class="native"></generator> </id> <property name="title" /> <property name="content" /> </class>

插入數據後使用下面代碼進行查詢測試:

public void query(){
        Session session = HibernateUtil.getSession();
        Transaction tx = null;
        try{
            tx = session.beginTransaction();
            News news=(News)session.load(News.class,21);//(1)
            System.out.println(news.getTitle());//(2)
        }catch(Exception e){
            
if(tx!=null){ tx.rollback(); } e.printStackTrace(); }finally{ HibernateUtil.closeSession(session); } }

解析:

  • 當運行到(1)處時,Hibernate並沒有發起對數據的查詢,如果我們此時通過一些調試工具,觀察此時news對象的內存快照,我們會驚奇的發現,此時返回實體對象的代理類對象,這裏所返回的對象類型就是News對象的代理類對象。
  • 當代碼運行到(2)處時,此時調用news.getTitle() 方法,發出Sql語句進行查詢。
  • 這樣,通過一個中間代理對象,Hibernate實現了實體的延遲加載,只有當用戶真正發起獲得實體對象屬性的動作時,才真正會發起數據庫查詢操作。所以實體的延遲加載是用通過中間代理類完成的,所以只有session.load()方法才會利用實體延遲加載,因為只有session.load()方法才會返回實體類的代理類對象。

3 集合類型的延遲加載

  • 在Hibernate的延遲加載機制中,針對集合類型的應用,意義是最為重大的,因為這有可能使性能得到大幅度的提高,我們在一對多關聯中,定義用來容納關聯對象的Set集合,並不是java.util.Set類型或其子類型,而是net.sf.hibernate.collection.Set類型,通過使用自定義集合類的實現,Hibernate實現了集合類型的延遲加載。
  • 要求News類中寫private Set editor;具體實現類讓Hibernate賦予。

為了對集合類型使用延遲加載,我們必須如下配置集合的關聯部分:

<!-- 集合的lazy屬性設置為true,則為集合類型的延遲加載-->
<set name="editor" table="editor" lazy="true">
    <key column="id"></key>
    <element type="string" column="name"></element>
</set>

通過將<set>元素的lazy屬性設置為true來開啟集合類型的延遲加載特性。

我們看下面插入數據和查詢的測試代碼:

//插入
News news = new News();
news.setTitle("title");
news.setContent("content");
Set editor = new HashSet();
editor.add("qinqin1");
editor.add("qinqin2");
news.setEditor(editor);
session.save(news);

//查詢
News news=(News)session.get(News.class,1);
//當集合lazy屬性為true,只有在調用集合的時候才會執行集合查詢語句,與使用get或load無關
    Set editor = news.getEditor();//(1)
    for(Object obj:editor){//(2)
        System.out.println(obj.toString());
    }

解析:

  當程序執行到(1)處時,這時並不會發起對關聯數據的查詢來加載關聯數據,只有運行到(2)處時,真正的數據讀取操作才會開始,這時Hibernate會根據緩存中符合條件的數據索引,來查找符合條件的實體對象。

4 屬性的延遲加載

  • 在Hibernate3中,引入了一種新的特性——屬性的延遲加載,這個機制又為獲取高性能查詢提供了有力的工具。在前面我們講大數據對象讀取時,在User對象中有一個resume字段,該字段是一個java.sql.Clob類型,包含了用戶的簡歷信息,當我們加載該對象時,我們不得不每一次都要加載這個字段,而不論我們是否真的需要它,而且這種大數據對象的讀取本身會帶來很大的性能開銷。
  • 在Hibernate3中,我們可以通過屬性延遲加載機制,來使我們獲得只有當我們真正需要操作這個字段時,才去讀取這個字段數據。
  • 屬性的延遲加載用的少,故了解

hibernate延遲加載