Hibernate4+EhCache配置二級緩存


本文主要講一講Hibernate+EhCache配置二級緩存的基本使用方法

(有關EhCache的基礎介紹可參見:http://sjsky.iteye.com/blog/1288257 )

 

Cache的多種配置方法

       Javabean cache的配置有三種,下面將一一介紹,具體如下::

        (1)bean中注解配置的方式: @Cache(usage = CacheConcurrencyStrategy.READ_WRITE,region="")

        (2)hibernate.cfg.xml中標簽配置方式: <class-cache class="" usage="" region=""/>

        (3)映射文件*.hb.xml中標簽配置方式: <cache usage=""  region=""/>

        (4)映射文件*.hb.xml中標簽配置方式: 使用spring配置文件 sessionFactory 下配置方式 

ehcache.xml配置說明

<diskStore>元素:指定一個文件目錄,當指定的內存不夠時,把數據寫到硬盤上時,將把數據寫到這個文件目錄下。 下面的參數這樣解釋:   

         user.home – 用戶主目錄    

         user.dir      – 用戶當前工作目錄   

         java.io.tmpdir – 默認臨時文件路徑

<defaultCache>元素:設定緩存的默認數據過期策略,如果沒有任何設置,將使用該策略。

<cache>元素:設定具體的命名緩存的數據過期策略。   

    name:cache唯一標識,通常為緩存對象的類名(非嚴格標准),如果為實體對象的包名稱.類名稱(如com.db.entity.User)時,那么實體的配置中可以省去<cache usage="read-write" region="regionName"/> 屬性的配置。如果不存在與類名匹配的cache名稱, 則用 defaultCache。如果類中包含set

    eternal:緩存是否永久有效 

    maxElementsInMemory:基於內存的緩存可存放對象的最大數目

    maxElementsOnDisk:基於硬盤的緩存可存放對象的最大數目

    overflowToDisk(true,false):緩存對象達到最大數后,將緩存寫到硬盤中 

    diskPersistent:硬盤持久化。指重啟JVM后,數據是否存在。默認為false。

    timeToIdleSeconds:設定允許對象處於空閑狀態的最長時間,以秒為單位。

    timeToLiveSeconds:設定對象允許存在於緩存中的最長時間,以秒為單位。

    diskExpiryThreadIntervalSeconds:對象檢測線程運行時間間隔。標識對象狀態的線程多長時間運行一次。

    diskSpoolBufferSizeMB:DiskStore使用的磁盤大小,默認值30MB。每個cache使用各自的DiskStore。

    memoryStoreEvictionPolicy:緩存清空策略 

        1.FIFO:first in first out 先講先出
        2.LFU: Less Frequently Used 一直以來最少被使用的
        3.LRU:Least Recently Userd 最近最少被使用

注意:

  如果要配置的實體有關聯關系,1、對於一對一 、多對一 ,只要將關聯對象也配置為二級緩存就可以了,否則,只緩存當前實體,對於關聯對象還是每次去數據庫中查詢的。2、 而對於一對多則需要 在 set  或 oneToMany上加 <cache usage="read-write"/> 或   @Cache(usage = CacheConcurrencyStrategy.READ_ONLY) ,這樣也只加載關聯對象的id集合,要完全緩存,則需要另外對關聯的對象也配置成使用二級緩存)3、對於多對多則無法緩存關聯對象,只能緩存當前對象,即使配置上面2中的所說的也無濟於事(反而配置了,第二次查詢時發出兩條sql,不配置的話 發出一條sql)

  如果使用了延遲加載,則關聯對象不會使用緩存,也就是說上面的說法都是在,沒有使用延遲加載的情況下才有效。

針對查詢緩存有兩個專用的標簽(其屬性與上面用法一致):

    <cache name="org.hibernate.cache.StandardQueryCache"
        maxElementsInMemory="50"
        eternal="false"
        timeToIdleSeconds="10"
        timeToLiveSeconds="10"
        overflowToDisk="false" />
    <cache name="org.hibernate.cache.UpdateTimestampsCache"
        maxElementsInMemory="5000"
        eternal="true"
        overflowToDisk="false" />      

      1. classpath:ehcahce.xml配置文件如下:

  Xml代碼

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">

    <diskStore path="java.io.tmpdir" />

    <defaultCache maxElementsInMemory="100" eternal="false"
        timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
        diskSpoolBufferSizeMB="30" maxElementsOnDisk="100" diskPersistent="false"
        diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"
        statistics="false" />

    <cache name="org.hibernate.cache.StandardQueryCache"
        maxElementsInMemory="5" eternal="false" timeToLiveSeconds="120"
        overflowToDisk="true" />

    <cache name="org.hibernate.cache.UpdateTimestampsCache"
        maxElementsInMemory="5000" eternal="true" overflowToDisk="true" />

    <cache name="simpleCache1"
        maxElementsInMemory="10000" maxElementsOnDisk="1000" eternal="false"
        overflowToDisk="true" diskSpoolBufferSizeMB="20" timeToIdleSeconds="300"
        timeToLiveSeconds="600" memoryStoreEvictionPolicy="LFU"
        transactionalMode="off" />

    <cache name="simpleCache2"
        maxElementsInMemory="1000" eternal="true" overflowToDisk="false"
        memoryStoreEvictionPolicy="FIFO" />

    <cache name="simpleCache3"
        maxElementsInMemory="1000" eternal="true" overflowToDisk="false"
        memoryStoreEvictionPolicy="FIFO" />
</ehcache>

    2.hibernate配置文件:hibernate.cfg.xml

  Xml代碼

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration  
    PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"  
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>
        <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/sampledb</property>
        <property name="connection.username">root</property>
        <property name="connection.password">123456</property>

        <property name="connection.useUnicode">true</property>
        <property name="connection.characterEncoding">UTF-8</property>
        <property name="connection.SetBigStringTryClob">true</property>
        <property name="connection.pool_size">10</property>
        <property name="hibernate.jdbc.batch_size">10</property>

        <property name="show_sql">true</property>
        <property name="format_sql">false</property>
        <property name="current_session_context_class">thread</property>
        <property name="hbm2ddl.auto">update</property>

        <!-- 配置二級緩存 -->
        <!-- hibernate4以前的版本 配置緩存的提供類-->
        <!-- <property name="hibernate.cache.provider_class">net.sf.ehcache.hibernate.SingletonEhCacheProvider</property> -->
         <!--hibernate4以后版本二級緩存的提供類-->
        <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
        <!-- 二級緩存配置文件的位置 -->
        <property name="hibernate.net.sf.ehcache.configurationResourceName">conf/ehcache.xml</property>
        <property name="hibernate.cache.use_second_level_cache">true</property>
        <property name="hibernate.cache.use_query_cache">true</property>

        <!-- 注解配置 -->
        <mapping class="michael.cache.ehcache.hibernate.EhUserInfo" />
        <mapping class="michael.cache.ehcache.hibernate.EhBlogTopic" />
        <mapping class="michael.cache.ehcache.hibernate.EhBlogTopic2" />

        <!-- 映射文件 -->
        <mapping resource="michael/cache/ehcache/hibernate/tb_EhBlogTopic3.hb.xml" />

        <!-- class-cache config -->
        <class-cache class="michael.cache.ehcache.hibernate.EhBlogTopic" usage="read-write" region="simpleCache1"/>

    </session-factory>
</hibernate-configuration>

 注:如果是Spring整合Hibernate,則可在Spring配置文件sessionFactory下配置,方法如下:

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.annotation.LocalSessionFactoryBean">
        <property name="entityCacheStrategies">
            <props>
                <prop key="michael.cache.hibernate.EhBlogTopic">read-write,simpleCache1</prop>
            </props>
        </property>
    </bean>

   3.相關javabean代碼片段如下:

      (1).hibernate.cfg.xml中<calss-cache>標簽配置的:EhBlogTopic.java:

  Java代碼 

/** 
 * @blog http://sjsky.iteye.com 
 * @author Michael 
 */  
@Entity  
@Table(name = "MY_TB_EH_BLOG_TOPIC")  
public class EhBlogTopic implements Serializable {  
  
    /** 
     * serialVersionUID 
     */  
    private static final long serialVersionUID = -570936907944909799L;  
  
    private Integer id;  
  
    private String userId;  
  
    private String topic;  
  
    private String site;  
  
    //其他省略  
}

 

    (2). bean中注解的方式配置cache的:EhBlogTopic2.java

/** 
 * @blog http://sjsky.iteye.com 
 * @author Michael 
 */  
@Entity  
@Table(name = "MY_TB_EH_BLOG_TOPIC2")  
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE,region="simpleCache2")  
public class EhBlogTopic2 implements Serializable {  
      //屬性和EhBlogTopic一樣  
     //其他省略  
}

    (3). 映射文件*.hb.xml中添加cache標簽的: EhBlogTopic3.java

  Java代碼

/** 
 * @blog http://sjsky.iteye.com 
 * @author Michael 
 */  
public class EhBlogTopic3 implements Serializable {  
   //屬性和EhBlogTopic一樣  
   //其他省略  
}  

     tb_EhBlogTopic3.hb.xml

  Xml代碼

<?xml version="1.0"?>  
<!DOCTYPE hibernate-mapping PUBLIC  
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"  
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="michael.cache.ehcache.hibernate">

    <class name="EhBlogTopic3" table="MY_TB_EH_BLOG_TOPIC3">
        <cache usage="read-write" region="simpleCache3"/>
        <id name="id" type="int" unsaved-value="null">
            <generator class="increment" />
        </id>
        <property name="userId" column="USER_ID" type="string" not-null="false" length="20" />
        <property name="topic" column="TOPIC" type="string" not-null="false" length="100" />
        <property name="site" column="SITE" type="string" not-null="false" length="100" />

    </class>
</hibernate-mapping>

      (4). 沒有配置cache的bean:EhUserInfo.java

  Java代碼

/** 
 * @blog http://sjsky.iteye.com 
 * @author Michael 
 */  
@Entity  
@Table(name = "MY_TB_EH_USER_INFO")  
public class EhUserInfo implements Serializable {  
  
    /** 
     * serialVersionUID 
     */  
    private static final long serialVersionUID = 930384253681679239L;  
  
    private Integer id;  
  
    private String userId;  
  
    private String userName;  
  
    private String otherInfo;  
  
    /** 
     * @return the id 
     */  
    @Id  
    @GeneratedValue  
    @Column(name = "ID")  
    public Integer getId() {  
        return id;  
    }  
  
  //其他省略。。。  
  
}  

   4.測試運行代碼如下:

  Java代碼   

/** 
 *  
 * @blog http://sjsky.iteye.com 
 * @author Michael 
 */  
public class TestEhcacheHibernate {  
  
    /** 
     * @param args 
     */  
    @SuppressWarnings("unchecked")  
    public static void main(String[] args) {  
        testMulitConfigMethod();  
    }  
  
    /** 
     * 測試多種配置緩存的方法 
     */  
    public static void testMulitConfigMethod() {  
        SessionFactory sessionFactory = null;  
        try {  
            System.out.println("ehcache - hibernate Test ...");  
            Configuration config = new AnnotationConfiguration()  
                    .configure("michael/cache/ehcache/hibernate/hibernate.cfg.xml");  
            System.out.println("hibernate config successful :" + config);  
            sessionFactory = config.buildSessionFactory();  
            Transaction ta = null;  
            try {  
                Session session = sessionFactory.getCurrentSession();  
                ta = session.beginTransaction();  
            } catch (Exception e) {  
                e.printStackTrace();  
                ta.rollback();  
            }  
            String[] cacheNames = CacheManager.getInstance().getCacheNames();  
            System.out.println("緩存的key cacheNames length := "  
                    + cacheNames.length + " 具體詳細列表如下:");  
            for (String name : cacheNames) {  
                System.out.println("name := " + name);  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        System.out.println("ehcache - hibernate Test end.");  
    }  
}  

 運行結果如下:

ehcache - hibernate Test ...

hibernate config successful :org.hibernate.cfg.AnnotationConfiguration@193c0cf

2011-12-15 11:32:36 net.sf.ehcache.hibernate.AbstractEhcacheProvider buildCache

警告: Could not find a specific ehcache configuration for cache named [michael.cache.ehcache.hibernate.EhBlogTopic]; using defaults.

2011-12-15 11:32:36 net.sf.ehcache.hibernate.AbstractEhcacheProvider buildCache

警告: Could not find a specific ehcache configuration for cache named [michael.cache.ehcache.hibernate.EhBlogTopic2]; using defaults.

2011-12-15 11:32:36 net.sf.ehcache.hibernate.AbstractEhcacheProvider buildCache

警告: Could not find a specific ehcache configuration for cache named [michael.cache.ehcache.hibernate.EhBlogTopic3]; using defaults.

2011-12-15 11:32:37 net.sf.ehcache.util.UpdateChecker doCheck

信息: New update(s) found: 2.4.6 [http://www.terracotta.org/confluence/display/release/Release+Notes+Ehcache+Core+2.4]. Please check http://ehcache.org for the latest version.

緩存的key cacheNames length := 7 具體詳細列表如下:

name := sampleCache2

name := michael.cache.ehcache.hibernate.EhBlogTopic2

name := org.hibernate.cache.UpdateTimestampsCache

name := sampleCache1

name := michael.cache.ehcache.hibernate.EhBlogTopic

name := org.hibernate.cache.StandardQueryCache

name := michael.cache.ehcache.hibernate.EhBlogTopic3

ehcache - hibernate Test end.

  從運行結果可見:三種方式的緩存配置都已經成功。

 

原文出自:http://jyao.iteye.com/blog/1315726


免責聲明!

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



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