1. 程式人生 > >Hibernate旅程(八)Hibernate快取機制--二級快取

Hibernate旅程(八)Hibernate快取機制--二級快取

Hibernate二級級快取

上篇介紹了一級快取,主要是session快取,session生命週期結束,快取也就結束。二級快取相對於一級快取來說是一個範圍更廣闊一些,就比你住的地方周圍有多個小賣鋪(session快取),和一個大型超市,原料加工廠送貨的時候送小賣鋪一份的同時,必然送一份到超市。而給第二個小賣鋪送一份的同時,也送給超市一份,這個超市就是我們的SessionFactoryhibernate二快取的又稱為“SessionFactory的快取快取的生命週期和SessionFactory(執行緒安全,一個數據庫對應一個,重量級)的生命週期一致,所以SessionFactory可以管理二級快取。

下面來看session控制的二級快取。

二級快取配置

1、需要引入第三方的jar包,hibernateCglib.jar

2、在快取的配置檔案來控制快取,我們可以拷貝hibernate已有專案中的ehcache.xml配置檔案到自己的專案中。通過這個檔案,我們可以對二級快取進行設定,例如快取的時間,快取的代銷,快取間隔多長時間自動被清掉,快取超時間直接快取到磁碟指定的位置上等設定。

3、hibernate.cfg.xml檔案中加入快取產品提供商。<propertyname="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

4、啟用二級快取,設定為true,預設是true,新增上有助於我們手動關閉和開啟二級快取。<propertyname="hibernate.cache.use_second_level_cache">true</property>

5、指定哪些實體類使用二級快取。

方法一:在對應實體的.hbm.xml檔案中設定,<cacheusage="read-only"/>這樣如果我們想要知道二百個對映檔案哪些使用了二級快取,就要檢視二百個檔案,所以我們可以把對實體加入二級快取的策略放到hibernate.cfg.xml進行配置。也就是方法二。

方法二:處於好管理的目的我們把哪個實體使用二級快取的配置放到

hibernate.cfg.xml檔案中。例如執行把student實體加入二級快取策略。<!--

指定Student使用二級快取

-->

<class-cacheclass="com.bjpowernode.hibernate.Student"usage="read-only"/>

注意:快取策略通常採用read-onlyread-write

快取原則;通常是讀大於寫的資料進行快取。

開啟二級快取在兩個session中使用兩次load()進行查詢

程式碼如下所示。

/**
    * 開啟二級快取
    *
    * 在兩個session中發load查詢
    */
   public voidtestCache1() {
      Sessionsession = null;
      try {
         session = HibernateUtils.getSession();
         session.beginTransaction();
         Studentstudent = (Student)session.load(Student.class, 1);
         System.out.println("student.name=" +student.getName());
         session.getTransaction().commit();
      }catch(Exceptione) {
         e.printStackTrace();
         session.getTransaction().rollback();
      }finally {
         HibernateUtils.closeSession(session);
      }
     
      try {
         session = HibernateUtils.getSession();
         session.beginTransaction();
         Studentstudent = (Student)session.load(Student.class, 1);
        
         //不會發出查詢語句,因為配置二級快取,session可以共享二級快取中的資料
         //二級快取是程序級的快取
         System.out.println("student.name=" +student.getName());
         session.getTransaction().commit();
      }catch(Exceptione) {
         e.printStackTrace();
         session.getTransaction().rollback();
      }finally {
         HibernateUtils.closeSession(session);
      }
     
   } 


列印結果如下圖所示。


由此可知,雖然我們使用的是兩個session,但第二次查詢的時候沒有再向資料庫發出查詢語句。也就是第一次查詢的時候放入session的同時也放入SessionFactory快取中一份,而第二個session再查詢的時候,就直接從二級快取中取出就可以了。

開啟二級快取在兩個session中使用兩次get()進行查詢。

程式碼就是把上述程式碼load方法改動為get方法。

執行結果如下所示。


load一樣,對於sessionFactory級別的快取,第二次查詢時就不再向資料庫發出查詢sql命令。

開啟二級快取,在兩個session中發出load查詢,採用SessionFactory管理二級快取

程式碼如下所示。

/**
    * 開啟二級快取
    * 
    * 在兩個session中發load查詢,採用SessionFactory管理二級快取
    */
   public voidtestCache3() {
      Sessionsession = null;
      try {
         session= HibernateUtils.getSession();
         session.beginTransaction();
         Studentstudent = (Student)session.load(Student.class, 1);
         System.out.println("student.name=" +student.getName());
         session.getTransaction().commit();
      }catch(Exceptione) {
         e.printStackTrace();
         session.getTransaction().rollback();
      }finally {
         HibernateUtils.closeSession(session);
      }
     
      //管理二級快取 (evict清除的意思)
      //HibernateUtils.getSessionFactory().evict(Student.class);
      HibernateUtils.getSessionFactory().evict(Student.class, 1);
     
      try {
         session= HibernateUtils.getSession();
         session.beginTransaction();
         Studentstudent = (Student)session.load(Student.class, 1);
        
         //會發出查詢語句,因為二級快取中的資料被清除了
         System.out.println("student.name=" +student.getName());
         session.getTransaction().commit();
      }catch(Exceptione) {
         e.printStackTrace();
         session.getTransaction().rollback();
      }finally {
         HibernateUtils.closeSession(session);
      }
   }


顯示結果如下所示。


根據顯示結果可知,在兩個session中發出load查詢,第一次放入session快取同時放入了二級快取sessionFactory中。在第二個session中,首先使用SessionFactory對二級快取管理,使用evict()方法清除二級快取,所以第二個session採用load查詢時,需要重新向資料庫傳送sql命令。

一級快取和二級快取互動

程式碼如下所示。

public voidtestCache4() {
      Sessionsession = null;
      try {
         session= HibernateUtils.getSession();
         session.beginTransaction();
         //禁止將一級快取中的資料放到二級快取中。快取模式設定為忽略。
         session.setCacheMode(CacheMode.IGNORE);
         Studentstudent =(Student)session.load(Student.class, 1);
         System.out.println("student.name=" + student.getName());
         session.getTransaction().commit();
      }catch(Exceptione) {
         e.printStackTrace();
         session.getTransaction().rollback();
      }finally {
         HibernateUtils.closeSession(session);
      }
 
      try {
         session= HibernateUtils.getSession();
         session.beginTransaction();
         Studentstudent = (Student)session.load(Student.class, 1);
        
         //會發出查詢語句,因為禁止了一級快取和二級快取的互動,一級快取沒有放到二級快取中。
         System.out.println("student.name=" +student.getName());
         session.getTransaction().commit();
      }catch(Exceptione) {
         e.printStackTrace();
         session.getTransaction().rollback();
      }finally {
         HibernateUtils.closeSession(session);
      }
   }


顯示結果如下所示。


從上圖可以看出,首先我們開啟session的事務,然後設定了當寫入session快取中的同時不寫入二級快取,session.setCacheMode(CacheMode.IGNORE),這樣第二個session再查詢的時候就不能從二級快取中找到相應的內容,仍需向資料庫發出sql請求。

大批量資料的新增。

當新增或更新大批量資料的時候,為了防止快取中資料量過大,我們可以設定刪除session一級快取,如果此時開啟二級快取,那麼也會同樣再二級快取中存放一份,這樣的話很可能會導致快取的溢位,所以對於大資料來說,如果放入了一級快取中,就應該禁止再放入二級快取中。

程式碼如下所示。

/**
    * 大批量的資料新增
    */
   public voidtestCache5() {
      Sessionsession = null;
      try {
         session= HibernateUtils.getSession();
         session.beginTransaction();
        
         //禁止一級快取和二級快取互動
         session.setCacheMode(CacheMode.IGNORE);
         for (int i=0;i<100; i++) {
            Studentstudent = new Student();
            student.setName("張三" +i);
            //一級快取放一份,二級快取也放一份。
            session.save(student);
            //每20條更新一次
            if (i %20 == 0) {
                session.flush();
                //清除快取的內容
                //只清除了一級快取中的內容,沒有清除一級快取中的內容。如果資料量過大,一樣溢位。
                //大於大資料量來說,如果配置了一級快取的話,就應該禁止再放入二級快取中。
                session.clear();
            }
         }
         session.getTransaction().commit();
      }catch(Exceptione) {
         e.printStackTrace();
         session.getTransaction().rollback();
      }finally {
         HibernateUtils.closeSession(session);
      }
   }    


控制檯列印sql如下圖所示。


Hibernate二級快取總結

從上可知,二級快取時比一級快取作用域更大,是在整個應用程式中。一級快取是不能被解除安裝的,是必需的,不允許也無法解除安裝,它是事務範圍的快取。而二級快取是可配置的,可解除安裝的,SessionFactory生命週期和應用程式整個過程對應,就有可能出現併發問題。

什麼樣的資料適合放到二級快取中?

1、很少被修改的資料

2、不是很重要的,並允許出現偶爾的併發資料

3、不會被併發的資料

4、常量資料

什麼樣的資料適不合放到二級快取中?

1、經常被修改的資料。

2、絕對不允許併發的資料。

3、與其他應用共享的資料。

相關推薦

Hibernate旅程Hibernate快取機制--二級快取

Hibernate二級級快取 上篇介紹了一級快取,主要是session快取,session生命週期結束,快取也就結束。二級快取相對於一級快取來說是一個範圍更廣闊一些,就比你住的地方周圍有多個小賣鋪(session快取),和一個大型超市,原料加工廠送貨的時候送小賣鋪一份的同時,必然送一份到超市。而給第二個小

Hibernate旅程Hibernate快取機制--一級快取

Hibernate一級快取 快取就是你去小賣鋪買東西,不用再去生產車間裡買東西,當小賣鋪倒閉了,也就是session快取生命週期結束。hibernate一級快取的宣告週期很短,和session的

Hibernate旅程Hibernate對資料庫刪除、查詢、更新操作

上篇,我們以向資料庫新增操作來演示hibernate對資料庫的其他操作,刪除、查詢、修改。 Hibernate對資料刪除操作 刪除User表中個一條資料,是需要更具User表的主鍵id值來刪除的。首

Hibernate學習———— Hibernate檢索策略(類級別,關聯級別,批量檢索)詳解

 序言          很多看起來很難的東西其實並不難,關鍵是看自己是否花費了時間和精力去看,如果一個東西你能看得懂,同樣的,別人也能看得懂,體現不出和別人的差距,所以當你覺得自己看了很多書或者學了很多東西的時候,你要想想,你花費的也就那麼一點時間,別人花你這麼多時間也能夠學到你所學到的東西,所以還是要繼

Hibernate旅程Hibernate對映--基本類對映和物件關係對映

回想一些我們在沒有學習ssh的時候,我們建立資料庫的表時,首先是資料庫建模E-R圖,然後再通過實體模型來建立關係模型,再建立相應的表。實體間存在三種關係,一對一,一對多(或者說多對一),多對多。

一口一口吃掉Hibernate——Hibernate中inverse的用法

設置 XML 示例代碼 映射文件 代碼 參加 property 如果 people 一、Inverse是hibernate雙向關系中的基本概念。inverse的真正作用就是指定由哪一方來維護之間的關聯關系。當一方中指定了“inverse=false”(默認),那麽那

Hibernate的一對多關聯關系

拋出異常 save -m 添加 屬性設置 ive 轉變 關系 hash 一、概述 例如,以客戶(Customer)和訂單(Order)為例,一個客戶能有多個訂單,一個訂單只能有一個客戶。 從Customer到Order是一對多關聯,在java類中的面向對象設計應該一個

hibernate學習hibernate的一級緩存&快照

class 執行 設置 update 原理 查看 技術分享 pri 比對 緩存:提高效率 硬件的 CPU緩存 硬盤緩存 內存 軟件的 io流緩存 hibernate 的一級緩存 也是為了操作數據庫的效率。 證明一級緩存在

Hibernate學習2- hibernate.cfg.xml詳解

source nec cfg 更新 閱讀 username 詳解 格式化sql BE 1:主配置文件主要分為三部分:    註意:通常情況下,一個session-factory節點代表一個數據庫;    1.1:第一部分       數據庫連接部分,註意"hibernate

ElasticSearch最佳入門實踐shard & replica 機制梳理以及單 node 環境中建立 index

1、shard & replica 機制梳理 (1)index包含多個shard (2)每個shard都是一個最小工作單元,承載部分資料,lucene例項,完整的建立索引和處理請求的能力 (3

Hibernate 教程[Hibernate物件的操作,物件CURD操作增刪改查]

準備 因為測試學習的時候我們每次建一個類都需要獲取Session,很麻煩。所以要把獲取Session的方法封裝成一個工具類 package uitl; import org.hibernate.Session; import org.hibernate.SessionFactory

Hibernate 教程[Hibernate物件的操作,xml配置,註解配置]

準備 資料庫建表(Hibernate可以自動生成表,和對應欄位,但是不能給欄位添加註釋,所以選擇手動建表) -- 建立表 CREATE TABLE `Event`( `id` INT AUTO_INCREMENT COMMENT '唯一標識', `title` VARC

Hibernate 教程[Hibernate的基本配置]

需要準備的東西 Hibernate官網 hibernate-release-5.4.0.Final.zip 官方架包 lib/required/目錄包含hibernate-corejar及其所有依賴項。無論使用哪種Hibernate功能,所有這些jar都必須在您的類路徑中

Hibernate學習———— hibernate一對一關係對映詳解

 一、一對一關係的概述       一對一關係看起來簡單,其實也挺複雜的。其中關係就包含了四種,單向雙向和主鍵關聯外來鍵關聯。 什麼意思呢,也就是包含了單向一對一主鍵關聯、雙向一對一主鍵關聯,單向一對一外來鍵關聯,雙向一對一外來鍵關聯, 這四種中,單雙向就不用在說了把,就是看你業務需求來去設定是否

Hibernate 學習Hibernate主鍵生成策略

生成主鍵的幾種形式 通過JPA的策略生成器來進行生成:JPA hibernate 其他的ORM框架照樣支援 GenerationType.TABLE,SEQUENCE Hiberante : foriegn uuid 自定義主鍵生成方式 TABLE快取

Hibernate——5持久化物件和一級快取機制

一、物件的三種狀態1、暫時態:當物件剛建立,和Session沒有發生任何關係時,當程式執行完就即刻消失,被稱為暫時態。2、持久態:當執行如下程式碼時,物件變為持久態Emp e = new Emp();s

Hibernate:基於外鍵映射的1-1關聯關系

hbm 初始化 inno oot type nat create getc source 背景: 一個部門只有一個一把手,這在程序開發中就會設計數據映射應該設置為一對一關聯。 在hibernate代碼開發中,實現這個業務有兩種方案: 1)基於外鍵映射的1-1關

MyBatis學習總結---快取機制

mybatis提供了快取機制減輕資料庫壓力,提高資料庫效能 mybatis的快取分為兩級:一級快取、二級快取 一級快取是SqlSession級別的快取,快取的資料只在SqlSession內有效 二級快取是mapper級別的快取,同一個namespace公用這一個快取,所以對SqlSess

Hibernate 5.3

Criteria 條件查詢是更具面向物件特色的資料查詢方式。它是一種型別安全的查詢方式,用來替代HQL。它是如何保證型別安全的呢?它使用的是強型別這種方式去構造criteria 查詢的,利用的就是靜態元模型。 靜態元模型 這個東西,是個什麼東東,我在簡單說一下

hibernateHQL(2)

BaseDAO需求 作用: 1、將賦值的操作交給basedao 2、分頁 a、查詢出符合條件的總記錄數 b、查詢符合條件的某一頁記錄 package com.zking.eight.dao; import java.util.Collection; i