Hibernate的三種狀態

1.Hibernate對象的三種狀態
sql

Hibernate中有三種狀態,對它的深刻理解,才能更好的理解hibernate的運行機理,剛開始不太注意這些概念,後來發現它是重要的。對於理解hibernateJVMsql的關係有更好的理解。對於須要持久化的JAVA對象,在它的生命週期中有三種狀態,並且互相轉化。
數據庫

1,  臨時狀態(Transient):new建立的對象,它沒有持久化,沒有處於Session中,處於此狀態的對象叫臨時對象; 緩存

2,  持久化狀態(Persistent):已經持久化,加入到了Session緩存中。如經過hibernate語句保存的對象。處於此狀態的對象叫持久對象; session

3,  遊離狀態(Detached):持久化對象脫離了Session的對象。如Session緩存被清空的對象。
特色:已經持久化,但不在
Session緩存中。處於此狀態的對象叫遊離對象; 分佈式

×√ spa

臨時狀態 hibernate

Transient) 線程

持久化狀態 代理

Persistent) xml

遊離狀態

Detached)

是否處於Session緩存中

×

×

數據庫中是否有對應記錄

×



三種狀態的區別以下:

1. 當對象處於Transient時,只在內存中有一個對象,沒ID,並且在緩存和數據庫中沒有;

2. 當對象處於save以後,內存、緩存都存在,有ID,並且當對象commit後數據庫也存在;

3.當對象處於Detached時,內存、緩存、數據庫都存在,並有ID,只是處於託管狀態;


如圖:


遊離對象和臨時對象異同:

二者都不會被Session關聯,對象屬性和數據庫可能不一致;

遊離對象有持久化對象關閉Session而轉化而來,在內存中還有對象因此此時就變成遊離狀態了;

Hibernate和SQL的關係:

在操做了hibernate的方法如save()等後,並無直接生成sql語句,去操做數據庫,而是把這些更新存入Session中,只有Session緩存要被更新時,底層的sql語句才能執行,數據存入數據庫;

下面舉例說明:
一,Session.save(user)運行機理。
1,把User對象加入緩存中,使它變成持久化對象;
2,選用映射文件指定的標識生成ID;
3,在Session清理緩存時候執行:在底層生成一個insert sql語句,把對象存入數據庫;

注意:在你執行Session.save(user)後,在Session清理緩存前,若是你修改user對象屬性值,那麼最終存入數據庫的值將是最後修改的值;此過程當中ID不能被修改;

二,Session.delete(user)運行過程。
若是user是持久化對象,則執行刪除操做,一樣底層數據庫的執行條件是:在Session清理緩存時候;
若是user是遊離對象:
1,將user對象和Session關聯,使之成爲持久化對象;
2,而後按照user 是持久化對象的過程執行;


       2. Session經常使用方法


 2. 1Session的兩個方法區分:


獲得Session的方法有以下兩個:


openSession :每次都是新的Session,而且要手動close


getCurrentSession:從上下文找,如已有那麼用已經有的Session,如沒有,建立新的;不須要手動close;


ps.   上下文具體指的是hibernate.cfg.xml中的current_session_context_class:


  <property name=」current_session_context_class」>thread</property>


current_session_context_class有四個值,兩個是經常使用的:


thread:在線程裏找是否有已經存在的Session;(最經常使用)


jta:主要針對數據庫分佈式而用;(處理多個數據庫事務)


2.2  delete :


delete(Object arg0); 當對象處於Detached後咱們就可使用delete進行刪除其對象;


2.3  load :


ss2.load(Class arg0, Serializable arg1);  返回Object,強制轉換下就OK了。


arg0:指的是你從數據庫取出數據當成arg0類型處理;


arg1:指的是主鍵;


 2.4. get : 


ss2.load(Class arg0, Serializable arg1); 與Load方法同樣能夠實現取出數據的功能;


              注意:  load 和 get的區別!


2.4.1.  load返回的只是代理對象,只有當你真正使用對象內容的時候纔會發出sql語句;而get則會直接從數據庫


加載,馬上發出sql語句,不會延遲;


2.4.2. 當使用不存在的數據時,load不會報錯,而get則確定會報錯;


       2.5 update:


update(Object arg0); 此種狀況效率很低,由於默認將全部字段都進行更新;


so, 能夠從數據庫中獲取到其對象後,直接set改變須要設置的屬性,而後當session進行commit時,hibernate默


認同步數據庫,如發現一致,不會發update的sql語句進行更新,當不一致的時候纔會發sql的update的語句,固然


此時更新也是所有字段進行更新,效率仍然偏低;


若是須要單獨更新一個字段,方法以下:


          2.5.1:修改註解(不靈活)當不須要更新時進行更新的屬性,使用註解@Column(updatable=false)


updatable默認爲true;


         2.5.2: 使用xml配置文件的話,可使用dynamic-update


         2.5.3: HQL(EJBQL) (推薦)


  2.6 :saveOrUpdate:


saveOrUpdate(Object o);   自動選擇save仍是update;


  2.7: clear:    


clear(); 主要用於清除session的緩存;


  2.8: flush(): flush(); 強制讓緩存內容與數據庫內容作同步,默認當session的commit時才同步;

相關文章
相關標籤/搜索