Hibernate的session詳解
一、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詳解