官术网_书友最值得收藏!

1.7 持久化類狀態

在應用程序中,持久化類的實例可能處于三種的不同狀態,Hibernate注重這三種狀態及其轉換,下面介紹持久化類實例的這三種狀態。

1.7.1 三種狀態

● 瞬時態(Transient)

也稱臨時狀態,該狀態的實例從未與任何持久化上下文(持久化上下文對應于Hibernate中的Session)關聯過,不和數據庫中的數據有任何關聯關系。

● 持久態(Persistent)

持久態實例與某個持久化上下文有關聯,它擁有持久化標識(相當于主鍵值),并且通常在數據庫中有一個對應的行。

● 脫管狀態(Detached)

也稱游離狀態,脫管態實例表示曾經與某個持久化上下文發生過關聯,不過那個上下文被關閉了。它擁有持久化標識,并且在數據庫中通常還存在一個對應的行,只是它已經不在持久化層的管理之下。

1.7.2 三種狀態之間的轉換

對于持久化過程中對象的生命周期,不同的ORM實現使用不同的術語,定義不同的狀態及狀態轉換。這里將繼續使用瞬時、持久、脫管三個術語,介紹對象如何在這三種狀態之間轉換。

如圖1.8所示,可以看到具體的持久管理器(Session)的方法,會觸發對象狀態的變化。在對象生命周期中,可以從瞬時狀態轉換到持久狀態,再轉換到脫管狀態。

圖1.8 Hibernate中的對象狀態及轉換

● 瞬時對象

在Hibernate中,使用new操作符初始化的對象,它們的狀態是瞬時的。也就是說它們沒有跟任何數據庫表的行相關聯,只要應用不再引用這些對象,它們的狀態將會丟失。這時,這些對象的生命期將會終止,變得不可訪問,交給垃圾回收機制來回收。瞬時對象狀態的修改不能在Hibernate的Session中被持久化。

Hibernate認為所有的瞬時對象都是非事務的,所以Hibernate不能對瞬時對象提供任何回滾功能。另外,僅僅被其他瞬時對象引用的對象也是瞬時的。

把對象從瞬時狀態轉換為持久狀態,可以調用Session的save()或saveOrUpdate()方法。

● 持久對象

在Hibernate中,持久對象是具有數據庫標識且在Session中的實例,持久對象有一個主鍵值設為數據庫標識符。持久對象可能來自瞬時對象被save或saveOrUpdate之后形成,也可能是通過get()或load()等方法從數據庫中檢索出來的對象。

持久對象是同Session相關的,是事務的,它們的狀態在事務結束時同數據庫進行同步。當事務提交時,通過執行SQL的INSERT、UPDATE和DELETE語句把內存中持久對象的狀態同步到數據庫中。不過,這個過程也可能在其他時間發生,例如Hibernate在執行查詢之前可能要求同數據庫同步(確保查詢能夠獲得事務早期所做的更改)。通常稱已經分配主鍵值但還沒有插入到數據庫中的持久對象是新的,新的持久對象將會一直保持“新”的狀態直到同步發生。

調用Session的close()和clear()等方法,持久對象脫離Session變成脫管對象,調用Session的delete()方法(數據庫中的對應記錄已被刪除),持久對象變成瞬時對象。

使對象持久化的示例代碼如下:

        //省略部分代碼
        Session session = sf.openSession();
        Seeker seeker = new Seeker();
        sesssion.save(seeker);
        tx.commit( );
        session.close( );

● 脫管(游離)對象

在Hibernate中,當事務結束時,同Session相關聯的持久對象仍然存在(如果事務成功,它們在內存中的狀態將會同數據庫同步,在數據庫中通常會有一條記錄對應)。當關閉Session時,這些對象就失去了同Session的關聯,一般把這些對象稱為脫管對象,表明這些對象的狀態不再跟數據庫同步(對它的修改僅發生在內存中),也不再在Hibernate持久化層的管理下。

應用程序通常在事務之外還要使用這些脫管對象,當這些對象重新同Session關聯時,這些對象又變成了持久狀態,例如在事務中調用saveOrUpdate(脫管對象),就會將該脫管對象變成持久對象。

使對象從持久狀態到脫管狀態再到持久狀態的示例代碼如下:

        //省略部分代碼
        Session sessionOne = sf.openSession();
        Seekerseeker=(Seeker)sessionOne.get(Seeker.class,"替換為id");
        System.out.println(seeker);
        sessionOne.close();                       //seeker對象成為脫管對象
        seeker.setName("zhang");
        seeker.setPassword("zhang");
        Session sessionTwo = sf.openSession();
        sessionTwo.update(seeker);                //重新關聯,seeker對象成為持久對象
        sessionTwo.beginTransaction().commit();   //seeker的狀態會同步到數據庫
        sessionTwo.close();

把持久對象轉換為瞬時對象的示例代碼如下:

        //省略部分代碼
        Session session = sf.openSession();
        Seekerseeker=(Seeker)sessionOne.get(Seeker.class,"替換為id");
        session.delete(seeker);
        session.beginTransaction().commit();
        session.close();
        //在這里還能使用seeker對象,但它已是瞬時狀態了

點評

在對象三種狀態中,通常最關心的是持久狀態的對象,它的最大特點是:對象處于Session管理范圍,且狀態會同步到數據庫中。另外兩種狀態與之相反,是再普通不過的內存中的對象,不同的是瞬時態的對象沒有數據庫標識,而脫管狀態的對象有數據庫標識。

主站蜘蛛池模板: 高州市| 库尔勒市| 丰原市| 邵阳县| 客服| 胶州市| 辽中县| 卫辉市| 东光县| 安庆市| 山东省| 巴彦淖尔市| 兰西县| 邵阳市| 渝中区| 永德县| 睢宁县| 遂川县| 平罗县| 射阳县| 彰化县| 惠安县| 阳春市| 娱乐| 拉孜县| 磐安县| 连平县| 敦煌市| 江源县| 临武县| 天祝| 商水县| 万盛区| 出国| 嫩江县| 武强县| 思南县| 南安市| 南部县| 潼南县| 东至县|