1.Hibernate把對象分文三種狀態:Transient(臨時狀態)、Persistent(持久化狀態)、Detached(游離狀態)。
1)Transient:剛剛new出來的對象,就是Transient狀態的,此時他沒有OID。
*獲得瞬時態對象
** User user=new User();
*瞬時態轉為持久態—獲得了相應的OID。
**session.save(user)
2)Persistent:有持久化標志OID,已經被納入到session對象的管理
*獲得持久化對象:
**get()/load()
*持久態轉為瞬時態對象
**delete() --比較有爭議,進入特殊的狀態,不太建議使用。
*持久態對象轉為游離態對象
**session的close()/evict()/clear()
3) Detached: --有持久化標志OID,但是沒有被納入到Session對象的管理
2注意:持久化對象有自動更新數據庫的能力,當持久化對象的屬性被改變時,調用Transaction的commit方法后,會對數據庫執行update SQL操作。注意,不能改變主鍵的值,否則會報錯。
3.三種狀態的區別:
*是否在Session對象管理下,如果在,則一定是持久態,否則是臨時太或者游離態。
*是否持有OID,沒有OID的是臨時狀態,有OID的是持久化狀態或者游離狀態。
臨時狀態 (Transient) |
持久化狀態 (Persistent) |
游離狀態 (Detached) |
|
是否處於Session緩存中 |
× |
√ |
× |
數據庫中是否有對應記錄 |
× |
√ |
√ |
是否有OID |
× |
√ |
√ |
4.Hibernate緩存
在Hibernate中,緩存是很重要的,它把數據緩存在內存中,提高了數據的訪問效率,存在兩級緩存
1)一級緩存 ——自帶的,不可卸載,以及緩存的生命周期和Session一致,一級緩存一般也稱為Session級別緩存。Session接口中,存在一系列的java集合,這些集合存着一級緩存的數據,當Session對象回收時,這些集合也就回收了。當在一個Session中查詢同一個對象時,是不會再次與數據庫交互的。
2)二級緩存 ——默認沒有開啟,需要手動配置才可以可以使用。二級緩存可以在多個Session中共享數據,二級緩存稱為是SessionFactory級別的緩存。
5.Hibernate采用快照模式。當數據對象被查詢出來之后,不僅在一級緩存中存有一份數據,在快照中也存了一份。當對象被改變時,只改變緩存區中的數據內容,不該表快照區的數據。提交事務(執行Transaction.commit()),首先對比緩存區和快照區的內容,如果一致,則不做任何操作;如果不一致,則把緩存區中的數據更新到數據庫,並把緩存區的數據也更新到快照區,形成新的快照。在對比的同時,完成對OID的驗證一致性驗證。
注意:只有數據變成了持久態之后,數據才有快照區副本。
6.數據庫的隔離級別分為4級,分別為:Serializable(8), Repeatable(4), Read committed(2)和Read uncommitted(1)。用一解決臟讀、不可重復讀、虛讀等隔離性問題。詳情可見:https://www.cnblogs.com/fjdingsd/p/5273008.html
*Hibernate通過hibernate.connection.isolation來配置隔離性。
7綁定本地Session
1)在javaWeb中使用JDBC時,一般都是在業務層開啟事務,那如何把同一個Connection傳遞下去,有兩種方法:
*一種是通過參數傳遞的方式
*另一種是吧Connection綁定到ThreadLocal對象中。
2)現在在hibernate框架中,使用Session對象開啟事物,所以需要傳遞session對象,框架提供了ThreadLocal的方式。
*需要在hibernate.cfg.xml中配置<property name=”hibernate.current_session_context_class>thread></property>
*使用SessionFactory的getCurrentSession()方法,獲取當前線程的Session對象。並且該Session對象不需要手動關閉,線程結束之后會自動關閉。
*注意:要想使用getCurrentSession()方法,必須提前配置。
*注意:在使用綁定本地Session時,Transaction也是在service層開啟的,而不是在DAO層。將事務維護交給service層。