hibernate 一級緩存(Session緩存)和持久化對象的四種狀態


1:持久化對象的四種狀態

  四種狀態分別為臨時狀態、持久化狀態、游離狀態和刪除狀態。

  這幾種狀態可以相互轉換

  狀態轉換圖:

  

  代碼演示:

  

 // 開啟事務  
  Transaction transaction = session.beginTransaction();   
  Book book = new Book(); // 瞬時態(沒有OID,未與Session關聯)  
  book.setName("hibernate精通");  
  book.setPrice(56d);    
  session.save(book);// 持久態(具有OID,與Session關聯)  
  // 提交事務,關閉Session  
  transaction.commit();  
  session.close();    
  System.out.println(book.getId()); // 脫管態(具有 OID,與Session斷開關聯) 

持久化對象之間轉變

    1.瞬態對象——通過new關鍵字獲取

      瞬時——持久:save、saveOrUpdate(都是通過session獲得)

      瞬時——脫管:對象.setID(1);為瞬時對象設置新的OID

    2.持久化對象——通過get/load、Query查詢獲得

      持久——瞬時:delete(被刪除持久化對象,不建議再次使用)

      持久——脫管:evict(清楚一級緩存中某個對象)、close(關閉Session,清除一級緩存)、clear(清楚一級緩存所有對象)

    3.脫管對象:無法直接獲得

      脫管——瞬時:對象.setID(null);刪除對象OID

      脫管——持久:update、saveOrUpdate、lock

    4.刪除狀態  :無法直接獲得

      持久——刪除:對象.delete();

      游離——刪除: 對象.delete();

 

2:一級緩存

  也成為session緩存,它和session生命周期相同,周期比較短,屬於事務隔離級別。

  hibernate的緩存是通過集合實現的,hibernate中封裝了list和map的集合。hibernate向一級緩存中存放數據時,同時保存快照數據,當執行flush()時,會對比一級緩存中的數據和快照中的數據是否一致,如果不一致,則執行更新。

  用處:

    當要查詢的數據在緩存中已經存在時,hibernate將不會再向數據庫發送查詢語句,而是直接從緩存中獲取對象。

    session.get()、load(支持一級緩存。createQuery()不支持一級緩存,即即使是兩次相同的查詢,獲得list也是相同的,也會向數據庫發起2次查詢

  操作:

    1:flush()

      將緩存同步到數據庫,首先會將緩存數據和快照區數據進行對比,如果相同,就不會發送update()語句,如果不同,則執行update()語句,所以不一定會很發生update()語句到數據庫。     

        session.beginTransaction();  
  
        // 通過ID從數據庫中獲取值,此時會產生快照  
        Book book1 = (Book) session.get(Book.class, 1);  
        // 修改屬性值  
        book1.setName("xxx");  
        // 手動flush,刷新緩存到數據庫,此時只是生成SQL語句,但是數據庫中並沒有發生變化,只有commit后,數據庫才會發生相應的變化。  
        session.flush();  
        // 手動提交事務  
        session.getTransaction().commit();  
        // 關閉session的資源  
        session.close();         

   2:refresh()

      將數據庫中的數據同步到緩存中,這個過程一定會產生更新語句,同步一級緩存和快照

        session.beginTransaction();  
  
        // 從數據庫中查詢book,並放置到Session緩存中一份  
          
        Book book1 = (Book) session.get(Book.class, 1);   
        //修改緩存對象的值  
        book1.setName("xxx");   
  
        //又進行了一次查詢操作,此時把快照中的數據與數據庫一致  
        session.refresh(book1);  
  
        System.out.println(book1);  
  
        // 4.提交食物  
        session.getTransaction().commit();  
        // 5.關閉session資源 
        session.close();    

    3:clear()

     清除所有對象的一級緩存,對對象的所有操作,全部失效,回復到當初和快照一樣

         // 啟動事務操作  
        session.beginTransaction();  
  
        // session.setFlushMode(FlushMode.MANUAL);  
  
        // 通過ID從數據庫中獲取值,此時會產生快照  
        Book book1 = (Book) session.get(Book.class, 1);  
        // 修改屬性值  
        book1.setName("xxx");  
        //清除一級緩存操作,此時當作事務提交的時候,數據庫中並沒有發生任何的變化  
        session.clear();  
        // 手動提交事務  
        session.getTransaction().commit();  
        // 關閉session的資源  
        session.close();      

    4:evict()

      對指定的對象清除一級緩存      

         session.beginTransaction();  
  
        //當執行一次操作后,會把對象放置到Session緩存中  
        Book book1 = (Book) session.get(Book.class, 1);  
        Book book2 = (Book) session.get(Book.class, 2);   
        session.evict(book2); // 從緩存中清除book2對象所做的修改  
        // 當再次執行操作時,book2還會發出SQL語句操作  
        Book book11 = (Book) session.get(Book.class, 1);   
        Book book22 = (Book) session.get(Book.class, 2);  
  
        // 手動提交事務  
        session.getTransaction().commit();  
        // 關閉資源  
        session.close();      

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM