Hibernate持久化物件的狀態

TZQ_DO_Dreamer發表於2014-11-06
1. 站在持久化的角度 , Hibernate 把物件分為 4 種狀態 : 持久化狀態, 臨時狀態, 遊離狀態(脫管狀態) , 刪除狀態.Session 的特定方法能使物件從一個狀態轉換到另一個狀態 .

2. 臨時狀態(Transient :
    1. 在使用代理主鍵的情況下 , OID 通常為 null
    2. 不處於 Session 的快取中
    3. 在資料庫中沒有對應的記錄

3. 持久化狀態(也叫”託管” ) Persist

    1. OID 不為 null
    2. 位於 Session 快取中
    3. 若在資料庫中已經有和其對應的記錄 , 持久化物件和資料庫中的相關記錄對應
    4. Session  flush 快取時 , 會根據持久化物件的屬性變化 , 來同步更新資料庫
    5. 在同一個 Session 例項的快取中 , 資料庫表中的每條記錄只對應唯一的持久化物件( Session 快取物件的 OID 不能重複)

    @Test
    public void testOID(){
        News news2 = (News ) session.get (News.class , 1);
        System.out.println (news2 );
    
        News news = new News ();
        news.setAuthor ("Oracle2" );
        news.setContent ("Oracle DB" );
        news.setDate (new Date ());
        news.setTitle ("DB" );
        news.setId (1 );
    
         //丟擲異常: org.hibernate.NonUniqueObjectException
        session.update (news );
    }

4. 遊離狀態(也叫”脫管” ) Detached ):
    1. OID 不為 null
    2. 不再處於 Session 快取中
    3. 一般情況需下 , 遊離物件是由持久化物件轉變過來的 , 因此在資料庫中可能還存在與它對應的記錄

5. 刪除狀態(Removed)
    1. 在資料庫中沒有和其 OID 對應的記錄
    2. 不再處於 Session 快取中
    3. 一般情況下 , 應用程式不該再使用被刪除的物件

6. 狀態的轉換圖

7. get & load 的區別:
    共同點:
    getload 從資料表中載入一個物件 , 載入後即為持久化狀態的物件
    不同點:
    get: 立即查詢資料表. 若沒有對應的記錄 , 返回 null 
    load: 延遲查詢資料表 . 直到第一次使用該物件時 , 再進行查詢,
    先返回的是一個代理物件 . 若沒有對應的記錄 ,並且使用了該物件 , 則會丟擲org.hibernate.ObjectNotFoundException 異常


8. update 方法:

    @Test
    public void testUpdate(){
        News news = (News ) session.get (News.class , 1);
        System.out.println (news );
    
        transaction.commit ();
        session.clear ();
    
        session = sessionFactory.openSession ();
        transaction = session.beginTransaction ();
    
         //此時物件為遊離狀態
        news.setAuthor ("Oracle" );
    
         //update 可以使遊離物件變為持久化物件 .
         //通常需要傳送一條 UPDATE 語句
         //若物件即為持久化物件 , 則不需要呼叫 update() 方法
        session.update (news );
    }

注意:
1 . 使用場景: B\S 專案中從頁面傳過來一個物件,需要對其進行更新時,即呼叫 update()方法
2 . 若資料表中沒有物件對應的記錄,還要執行 update() 方法,則會丟擲異常: org.hibernate.StaleObjectStateException

9. saveOrUpdate (): 儲存或更新

11. delete ():刪除一個物件對應的記錄。
    1. 若只想刪除指定的物件,設定 ID 即可。
    2. 若資料表中沒有對應的記錄,則丟擲異常: java.lang.IllegalArgumentException

12. Hibernate 呼叫原生的 JDBC API

    session.doWork(new Work() {
        @Override
        public void execute(Connection connection ) throws SQLException {
             //使用 JDBC 原生的 API
         }
    });


相關文章