hibernate中的物件有三種狀態: 瞬時狀態 (Transient),持久狀態 (Persistent),脫管狀態(Detached)
1. 瞬時狀態 (Transient)
當我們透過Java的new關鍵字來產生一個實體物件時,這時這個實體物件就處於自由狀態,如下:
Customer customer=new Customer(“zx”,27,images);
這時customer物件就處於自由狀態,為什麼說customer物件處於自由狀態呢?這是因為,此時customer只是透過JVM獲得了一塊記憶體空間,還沒有透過Session物件的save()方法儲存進資料庫,因此也就還沒有納入Hibernate的快取管理中,也就是說customer物件現在還自由的遊蕩於Hibernate快取管理之外。所以我們可以看出自由物件最大的特點就是,在資料庫中不存在一條與它對應的記錄。
瞬時物件特性:
(1) 不和 Session 實例關聯
(2) 在資料庫中沒有和瞬時物件關聯的記錄
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) 物件。
瞬時物件轉為持久物件:
(1) 透過 Session 的 save() 與 saveOrUpdate() 方法把一個瞬時物件與資料庫連結,這個瞬時對象就成為持久化對象。
(2) 使用 fine(),get(),load() 和 iterater() 待方法查詢到的資料對象,將成為持久化物件。
持久化物件的特性:
(1) 與 Session 執行個體關聯
(2) 在資料庫中有和持久性物件關聯的記錄
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 關閉後,物件就變成脫管物件。對脫管物件的引用依然有效,物件可繼續被修改。
脫管物件特性:
(1) 本質上和瞬時物件相同
(2) 只是比爱瞬时对象多了一个数据库记录标识值 id.
持久对象转为脱管对象:
当执行 close() 或 clear(),evict() 之后,持久对象会变为脱管对象。
瞬时对象转为持久对象:
通过 Session 的 update(),saveOrUpdate() 和 lock() 等方法,把脱管对象变为持久对象。
三种状态相互转化的状态图如下:
4 .结合 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); // 提交事务,关闭 Session2
注:即使把 session2.update(stu); 这句去掉,提交事务时仍然会执行一条 update() 语句。
如果希望只有脱管对象改变了, Hibernate 才生成 update 语句,可以把映射文件中
(3)saveOrUpdate() 方法兼具 save() 和 update() 方法的功能,对于传入的对象, saveOrUpdate() 首先判断其是脱管对象还是临时对象,然后调用合适的方法。
以上就是Hibernate中对象的三种状态及相互转化的内容,更多相关内容请关注PHP中文网(www.php.cn)!