zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Props VS State
    Component VS PureComponent
    Webpack loaders
    近期需要学习的技术
    jQuery源码解读三选择器
    jQuery源码解读二(apply和call)
    jQuery源码解读一
    Web语义化
    如何用python语言撸出图表系统
    抓取android系统日志_记录一次定位app闪退故障
  • 原文地址:https://www.cnblogs.com/SaraMoring/p/5646200.html
Copyright © 2011-2022 走看看