1. 程式人生 > >Hibernate的session詳解

Hibernate的session詳解

有一個 ans 默認值 ola Opens bubuko 配置文件 update 映射

一、hibernate的session介紹

Session 具有一個緩存, 位於緩存中的對象稱為持久化對象, 它和數據庫中的相關記錄對應。Session 能夠在某些時間點, 按照緩存中對象的變化來執行相關的 SQL 語句, 來同步更新數據庫, 這一過程被稱為刷新緩存(flush)。也叫一級緩存。
在 Session 接口的實現中包含一系列的 Java 集合, 這些 Java 集合構成了 Session 緩存。 只要 Session 實例沒有結束生命周期, 且沒有清理緩存,則存放在它緩存中的對象也不會結束生命周期。Session 緩存可減少 Hibernate 應用程序訪問數據庫的頻率。

 session緩存的示例:

    @Test
    public void getUser(){
        User user=session.get(User.class,1);
        User user2=session.get(User.class,1);
        System.out.println(user);
        System.out.println(user2);//查詢出來的兩條記錄完全一樣
    }

技術分享圖片

二、session緩存的操作方法:

  技術分享圖片

(1)flush方法:session會按照緩存中對象屬性的變化來更新數據庫中的記錄,使數據庫中記錄和緩存中的對象保持一致,默認情況下,在以下時間點會刷新緩存:

  ①:當應用程序調用Transaction.commit()方法時,該方法會先調用flush()方法,然後提交事物

  ②:顯示的調用flush()方法時

  ③:當應用程序執行一些查詢(HQL, Criteria)操作時,如果緩存中持久化對象的屬性已經發生了變化,會先 flush 緩存,以保證查詢結果能夠反映持久化對象的最新狀態

flush 緩存的例外情況:

  如果對象使用 native 生成器生成 OID, 那麽當調用 Session 的 save() 方法保存對象時, 會立即執行向數據庫插入該實體的 insert 語句.

  hibernate的主鍵生成策略:

  技術分享圖片

flush()和commit()方法的區別:

  flush()方法會執行一系列的sql語句,但是不會提交事物;commit()在提交事物前,會先調用flush()方法,然後i在提交事物,提交事物以為這將數據庫的操作永久的保存下來

(2)refresh:

  refresh會強制發送select語句, 以使數據庫中的記錄和緩存中的對象保持一致;如果在調用refresh方法前,手動的修改數據庫中的記錄,查詢出來的結果還不是最新的,這跟數據庫的數據的隔離級別是相關的,可以在配置文件中顯示的修改事物的隔離級別,每一個隔離級別都對應一個整數;

<property name="hibernate.connection.isolation">2</property>

Oracle 支持的 2 種事務隔離級別:READ COMMITED, SERIALIZABLE. Oracle 默認的事務隔離級別為: READ COMMITED ,mysql支持四中事物的隔離級別:

  1. READ UNCOMMITED
  2. READ COMMITED
  4. REPEATABLE READ
  8. SERIALIZEABLE

(3)clear 清理緩存

三、持久化對象的狀態

  持久化對象狀態分為四種狀態:持久化狀態, 臨時狀態, 遊離狀態, 刪除狀態。Session 的特定方法能使對象從一個狀態轉換到另一個狀態;

技術分享圖片

(1)update方法:

  ①:若更新一個持久化對象,不必顯示的調用update()方法,因為在嗲用Transaction的commit()方法時,會調用session的flush()

  ②:更新一個遊離對象,需要顯示的調用update()方法,可以將一個遊離對象轉換為持久化對象

  ③:當 update() 方法關聯一個遊離對象時, 如果在 Session 的緩存中已經存在相同 OID 的持久化對象, 會拋出異常

  ④:當 update() 方法關聯一個遊離對象時, 如果在數據庫中不存在相應的記錄, 也會拋出異常.

    @Test
    public void testUpdate(){
        User user=session.get(User.class,1);
        transaction.commit();
        session.close();
        session=sessionFactory.openSession();
        transaction=session.beginTransaction();
        user.setUserName("James");//會發送update()語句
        //但是如果不修改user的任何屬性,也會發送update語句,如何避免盲目的發送sql?
        // 可以通過在hbm.xml文件的class標簽中加入select-before-update="true" ,默認為false
        session.update(user);
    }

(2)saveOrUpdate:

  如果user是臨時對象,則調用save()方法,如果user是遊離對象,則調用update()方法

  判斷對象是不是臨時對象:

    ①:Java 對象的 OID 為 null

    ②:映射文件中為 <id> 設置了 unsaved-value 屬性, 並且 Java 對象的 OID 取值與這個 unsaved-value 屬性值匹配

(3)delete

  刪除操作,如果OID和數據庫中的一條記錄保持一致,則執行刪除操作,,把對象從 Session 緩存中刪除, 該對象進入刪除狀態,若OID在數據庫中沒有對應的記錄,則拋出異常,Hibernate 的 cfg.xml 配置文件中有一個 hibernate.use_identifier_rollback 屬性, 其默認值為 false, 若把它設為 true, 將改變 delete() 方法的運行行為: delete() 方法會把持久化對象或遊離對象的 OID 設置為 null, 使它們變為臨時對象

  

Hibernate的session詳解