hibernate 中物件的3種狀態總結
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層。