Hibernate(四)之對象狀態及一級緩衝

來源:互聯網
上載者:User

標籤:images   --   操作   mit   log   png   優先   pass   lap   

一、Hibernate中的對象狀態  1.1、瞬時態(臨時態)

    沒有與Hibernate產生關聯

    與資料庫中的記錄沒有產生關聯(有關聯就是與資料庫中表的id相對應)   

      獲得:一般都只直接建立(new)
      瞬時態 轉換 持久態
        一般操作:save方法、saveOrUpdate
      瞬時態 轉換 脫管態
        一般操作:通過setId方法設定資料

   1.2、持久態

    Hibernate有關聯

    對象有id

      獲得:
        查詢操作:get、loat、createQuery、createCriteria 等 獲得都是持久態【】
        執行save之後持久態
        執行update之後持久態
      持久態 轉換 瞬時態
        官方規定執行delete() --民間:刪除態
      持久態 轉換 脫管態
        session沒有記錄
        session.close () 關閉
        session.clear() 清除所有
        session.evict(obj) 清除指定的PO對象

  1.3、游離態(脫管態)

    沒有與Hibernate產生關聯

    對象有ID

      獲得:
        建立、並設定OID的
        通過api獲得
      脫管態 轉換 瞬時態
        手動去除OID,設定成預設值
      脫管態 轉換 持久態
        一般操作:update()、saveOrUpdate

  1.4、在代碼中去查看三種狀態

    

  1.5、三種狀態的相互轉換    1.5.1、瞬時轉化為持久

    

      注意:如果主鍵建置原則中value是assigned需要自己指定主鍵,不指定會報錯。

    1.5.2、瞬時轉化為游離  

        在資料庫中id=1中已經存在有

        

        

    1.5.3、持久轉化為瞬時

      

      方式二:

          

    1.5.4、持久轉化為游離

      

    1.5.5、游離轉化為瞬時

      

    1.5.6、游離轉化為持久

      

  1.6、三種狀態有什麼用處?

    持久狀態,我們使用Hibernate主要是為了持久化我們的資料.

    對於對象的狀態,我們期望我們需要同步到資料庫的資料,都被裝換成持久狀態

    持久化狀態特點: Hibernate會自動將持久化狀態物件的變化同步到資料庫中.  

    

二、一級緩衝

    又稱為session層級的緩衝。當獲得一次會話(session),hibernate在session中建立多個集合(map),用於存放操作資料(PO對象),為程式最佳化服務,

    如果之後需要相應的資料,hibernate優先從session緩衝中擷取,如果有就使用;如果沒有再查詢資料庫。當session關閉時,一級緩衝銷毀。

  在Hibernate中存在兩種緩衝:一是線程層級的緩衝(session緩衝)二是進程層級的緩衝(二級緩衝)

  緩衝:用來提高效率的

    session緩衝:就是session對象中存在的緩衝,緩衝中存在的是(持久化)對象。

  2.1、證明session緩衝的存在

    

    我們用圖形來理解:

      

  2.2、一級緩衝快照

        在從資料庫取資料時,會將資料一式兩份,一份作為緩衝中的對象,一份作為快照,在session提交時做對比。

      快照:與一級緩衝一樣的存放位置,對一級快取資料備份。保證資料庫的資料與 一級緩衝的資料必須一致。如果一級緩衝修改了,

          在執行commit提交時,將自動重新整理一級緩衝,執行update語句,將一級緩衝的資料更新到資料庫。

        

 

          

    舉例:

      

    我們畫圖來分析一下: 

          

        

      持久化狀態: 本質就是存在緩衝中的對象,就是持久化狀態.

  2.3、感受一級緩衝帶來的效率

      感受一:

    

      從上面這三行代碼中,我們u1執行需要執行一條sql語句,我們執行得到u2和u3時,發現不會去重新查詢,而是從緩衝中找。

      感受二:

        

        從上面代碼還在那個我們知道,第一個u1中會執行select語句。當事務還沒有提交的時候,只會在緩衝中進行。

        所以總的只會產生兩條sql語句。

  2.4、一級緩衝中的細節問題

    問題一:儲存對象時,可以使用save方法和persist方法,他們之間有區別嗎?

        沒有區別,功能上是一樣的。但persist(持久) 方法 來自於JPA 介面。而save(儲存) 方法來自於Hibernate。

    問題二:HQL查詢是否會使用一級緩衝?

        HQL不會使用一級緩衝.

    

    問題三:HQL語句批量查詢時,查詢結果是否會進入緩衝?

        查詢結果會放入緩衝中

    

    問題四:SQL查詢 結果會不會放入1級緩衝中?

        如果把查詢結果封裝到對象中,對象會放入一級緩衝

      

    問題五:SQL查詢 結果會不會放入1級緩衝中?

        沒有把查詢結果封裝到對象中,對象不會放入一級緩衝

          

    問題六:criteria  會將查詢結果放入一級緩衝. 但是查詢不會使用一級緩衝. 與Hql查詢結論一致.    

三、session中的其他API

    evict()方法:將緩衝中的對象刪除

    clear()方法:清空一級緩衝

    refresh方法:重新整理,強制重新整理緩衝中的對象 => (可以用來解決緩衝與資料庫資料不同步的問題)

    

    flush方法:對比快照,並提交緩衝對象

import java.util.List;import org.hibernate.Session;import org.junit.Test;import com.itheima.domain.User;import com.itheima.utils.HibernateUtils;//其他API (大部分都是瞭解)public class Demo1 {    @Test    //1. evict 將緩衝中的對象移除.    //2. clear 清空1級緩衝     public void fun1(){        Session session = HibernateUtils.openSession();        session.beginTransaction();        //------------------------------------------------        User u1 = (User) session.get(User.class, 1);                session.clear();                User u2 = (User) session.get(User.class, 1);                //------------------------------------------------        session.getTransaction().commit();        session.close(); // 游離狀態    }    @Test    //3 refresh 重新整理 => 強制重新整理緩衝中的對象 => (可以用來解決緩衝與資料庫資料不同步的問題)    public void fun2(){        Session session = HibernateUtils.openSession();        session.beginTransaction();        //------------------------------------------------        User u1 = (User) session.get(User.class, 1);                session.refresh(u1); //將緩衝中的對象立刻與資料庫同步,會再發送一個sql語句        //------------------------------------------------        session.getTransaction().commit();        session.close(); // 游離狀態    }    @Test    //4 flush 對比快照,並提交緩衝對象    public void fun3(){        Session session = HibernateUtils.openSession();        session.beginTransaction();        //------------------------------------------------        User u1 = (User) session.get(User.class, 1);                //u1.setName("zhangsan");                session.flush();// 立刻提交session緩衝中的對象到資料庫                //------------------------------------------------        session.getTransaction().commit();        session.close(); // 游離狀態    }        @Test    // 代理主鍵=> native    //5.1 aveOrUpdate方法    //saveOrUpdate 可以同時完成儲存或更新操作    //主鍵為空白=>save    //主鍵有值=> update    public void fun4(){        Session session = HibernateUtils.openSession();        session.beginTransaction();        //------------------------------------------------        User u = new User();        u.setId(99);        u.setName("jack");        u.setPassword("1234");                session.saveOrUpdate(u);        //------------------------------------------------        session.getTransaction().commit();        session.close(); // 游離狀態    }        // 自然主鍵=> assigned    //5 update 與 saveOrUpdate方法        //saveOrUpdate 可以同時完成儲存或更新操作        //主鍵為空白=> 報錯,因為無論是save還是update 都必須指定id        //主鍵有值=> 先會根據主鍵查詢資料庫.                // 資料庫中存在=> 執行update                // 資料庫中不存在=> 執行insert    @Test        public void fun5(){            Session session = HibernateUtils.openSession();            session.beginTransaction();            //------------------------------------------------            User u = new User();            u.setId(88);            u.setName("jack01");            u.setPassword("1234");                        session.saveOrUpdate(u);            //------------------------------------------------            session.getTransaction().commit();            session.close(); // 游離狀態        }            @Test    //在我們使用Hibernate時候,注意要避免出現,兩個相同的ID對象.放入一級緩衝的情況.    public void fun6(){        Session session = HibernateUtils.openSession();        session.beginTransaction();        //------------------------------------------------        User u = (User) session.get(User.class, 1);// 持久化,緩衝中存在                session.evict(u); // 游離態,緩衝中不存在                User u2 = (User) session.get(User.class, 1);// 持久化,緩衝中存在                session.update(u); // 將U重新變為持久化狀態,緩衝中存在        //------------------------------------------------        session.getTransaction().commit();        session.close(); // 游離狀態    }}
testSessionApi

 

 

  

 

  

 

 

 

    

 

 

 

 

    

 

    

 

    

 

 

 

  

    

 

 

      

 

 

 

    

    

    

 

Hibernate(四)之對象狀態及一級緩衝

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.