SSH架構之-hibernate 三種狀態的轉換,ssh-hibernate

來源:互聯網
上載者:User

SSH架構之-hibernate 三種狀態的轉換,ssh-hibernate
一、遇到的神奇的事情

使用jpa操作資料庫,當我使用findAll()方法查處一個List的對象後,給對這個list的實體進行了一些操作,並沒有調用update 或者 saveOrUpdate方法,更改後的資料卻神奇的儲存到資料庫裡面去了。

最後簡單粗暴的解決辦法是把這份從資料裡面查出來的List 複製了一份,然後再操作,再返回。資料就正常了,資料庫也沒更新。後面找了資料才發現是jpa是對hibernate的封裝,底層是hibernate,這是hibernate的持久狀態搞的鬼。

二、hibernate 的三種狀態

1. 瞬時狀態 (Transient)

當我們通過Java的new關鍵字來產生一個實體物件時,這時這個實體物件就處於自由狀態,如下:

1 Customer customer=new Customer(“zx”,27,images); 這時customer對象就處於自由狀態,為什麼說customer對象處於自由狀態呢?這是因為,此時customer只是通過JVM獲得了一塊記憶體空間,還並沒有通過Session對象的save()方法儲存進資料庫,因此也就還沒有納入Hibernate的緩衝管理中,也就是說customer對象現在還自由的遊盪於Hibernate緩衝管理之外。所以我們可以看出自由對象最大的特點就是,在資料庫中不存在一條與它對應的記錄。

瞬時對象特點: 不和 Session 執行個體關聯 在資料庫中沒有和瞬時對象關聯的記錄

2. 持久狀態 (Persistent)

持久化對象就是已經被儲存進資料庫的實體物件,並且這個實體物件現在還處於Hibernate的緩衝管理之中。這是對該實體物件的任何修改,都會在清理緩衝時同步到資料庫中。如下所示:

Customer customer=new Customer(“zx”,27,images);

tx=session.beginTransaction();

session.save(customer);

customer=(Customer)session.load(Customer.class,”1”);

customer.setAge(28);

tx.commit();

這時我們並沒有顯示調用session.update()方法來儲存更新,但是對實體物件的修改還是會同步更新到資料庫中,因為此時customer對象通過save方法儲存進資料庫後,已經是持久化對象了,然後通過load方法再次載入它,它仍然是持久化對象,所以它還處於Hibernate緩衝的管理之中,這時當執行tx.commit()方法時,Hibernate會自動清理緩衝,並且自動將持久化對象的屬性變化同步到到資料庫中。

持久的執行個體在資料庫中有對應的記錄,並擁有一個持久化標識 (identifier).

持久對象總是與 Session 和 Transaction 相關聯,在一個 Session 中,對持久對象的改變不會馬上對資料庫進行變更,而必須在 Transaction 終止,也就是執行 commit() 之後,才在資料庫中真正運行 SQL 進行變更,持久對象的狀態才會與資料庫進行同步。在同步之前的持久對象稱為髒 (dirty) 對象。

瞬時對象轉為持久對象:

通過 Session 的 save() 和 saveOrUpdate() 方法把一個瞬時對象與資料庫相關聯,這個瞬時對象就成為持久化對象。 使用 fine(),get(),load() 和 iterater() 待方法查詢到的資料對象,將成為持久化對象。 持久化對象的特點:

和 Session 執行個體關聯 在資料庫中有和持久對象關聯的記錄 3. 脫管狀態 (Detached)

當一個持久化對象,脫離開Hibernate的緩衝管理後,它就處於游離狀態,游離對象和自由對象的最大區別在於,游離對象在資料庫中可能還存在一條與它對應的記錄,只是現在這個游離對象脫離了Hibernate的緩衝管理,而自由對象不會在資料庫中出現與它對應的資料記錄。如下所示:

Customer customer=new Customer(“zx”,27,images);

tx=session.beginTransaction();

session.save(customer);

customer=(Customer)session.load(Customer.class,”1”);

customer.setAge(28);

tx.commit();

session.close();

當session關閉後,customer對象就不處於Hibernate的緩衝管理之中了,但是此時在資料庫中還存在一條與customer對象對應的資料記錄,所以此時customer對象處於游離態 與持久對象關聯的 Session 被關閉後,對象就變為脫管對象。對脫管對象的引用依然有效,對象可繼續被修改。

脫管對象特點:

本質上和瞬時對象相同 只是比愛瞬時對象多了一個資料庫記錄標識值 id. 持久對象轉為脫管對象:

當執行 close() 或 clear(),evict() 之後,持久對象會變為脫管對象。

瞬時對象轉為持久對象:

通過 Session 的 update(),saveOrUpdate() 和 lock() 等方法,把脫管對象變為持久對象。

三、三種狀態的轉換

 

 

四、舉例子

結合 save(),update(),saveOrUpdate() 方法說明對象的狀態

(1) Save() 方法將瞬時對象儲存到資料庫,對象的臨時狀態將變為持久化狀態。當對象在持久化狀態時,它一直位於 Session 的緩衝中,對它的任何操作在事務提交時都將同步到資料庫,因此,對一個已經持久的對象調用 save()或 update() 方法是沒有意義的。如:

Student stu = new Strudnet();

stu.setCarId(“200234567”);

stu.setId(“100”);

// 開啟 Session, 開啟事務

session.save(stu);

stu.setCardId(“20076548”);

session.save(stu); // 無效

session.update(stu); // 無效

// 提交事務,關閉 Session (2) update() 方法兩種用途重新關聯脫管對象為持久化狀態物件,顯示調用 update() 以更新對象。調用 update() 只為了關聯一個脫管對象到持久狀態,當對象已經是持久狀態時,調用 update() 就沒有多大意義了。如:

// 開啟 session ,開啟事務

stu = (Student)session.get(Student.class,”123456”);

stu.setName(“Body”);

session.update(stu); // 由於 stu 是持久對象,必然位於 Session 緩衝中,

對 stu 所做的變更將 // 被同步到資料庫中。所以 update() 是沒有意義的,可以不要這句效果一樣的。

// 提交事務,關閉 Session

Hibernate 總是執行 update 語句,不管這個脫管對象在離開 Session 之後有沒有更改過,在清理緩衝時 Hibernate總是發送一條 update 語句,以確保脫管對象和資料庫記錄的資料一致,如:

Student stu = new Strudnet();

stu.setCarId(“1234”);

// 開啟 Session1, 開啟事務

session1.save(stu);

// 提交事務,關閉 Session1

stu.set(“4567”); // 對脫管對象變更

// 開啟 Session2, 開啟事務

session2.update(stu);ssh

// 提交事務,關閉 Session2

註:即使把 session2.update(stu); 這句去掉,提交事務時仍然會執行一條 update() 語句。

如果希望只有脫管對象改變了, Hibernate 才產生 update 語句,可以把對應檔中 標籤的 select-before-update 設為 true, 這種會先發送一條 select 語句取得資料庫中的值,判斷值是否相同,如果相同就不執行 update語句。不過這種做法有一定的缺點,每次 update 語句之前總是要發送一條多餘的 select 語句,影響效能。對於偶爾更改的類,設定才是有效,對於經常要更改的類這樣做是影響效率的。

(3) saveOrUpdate() 方法兼具 save() 和 update() 方法的功能,對於傳入的對象, saveOrUpdate() 首先判斷其是脫管對象還是臨時對象,然後調用合適的方法。

參考

Hibernate 實體物件的狀態及轉化 by javacoffe

推薦一個交流學習群:650385180裡面會分享一些資深架構師錄製的視頻錄影:有Spring,MyBatis,Netty源碼分析,高並發、高效能、分布式、微服務架構的原理,JVM效能最佳化這些成為架構師必備的知識體系。還能領取免費的學習資源,目前受益良多:

 

註:喜歡的朋友可以點贊加關注,一起學習進步

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.