zoukankan      html  css  js  c++  java
  • Hibernate-ORM:16.Hibernate中的二级缓存Ehcache的配置

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------

    本篇博客讲述Hibernate中的二级缓存的配置,作者将使用的是ehcache缓存

    一,目录

      1.二级缓存的具体配置 

        1.1  jar包的引用和注意事项

        1.2  ehcache.xml的配置

        1.3  集成到hibernate.cfg.xml

        1.4  需要使用二级缓存的 XXXX.hbm.xml中的配置

      2.二级缓存的测试方法

        2.1  测试是否配通,二级缓存存在性的证明

        2.2  在二级缓存中设置readonly

        2.3  设置二级缓存的模式

    二,二级缓存的具体配置

      1.jar包的引用和注意事项(我合起来了,用的话打开)

            <!--Hibernate的核心jar-->
            <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-core</artifactId>
                <version>5.2.12.Final</version>
            </dependency>
            <!--配置需要的ehcahe插件-->
            <!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache -->
            <dependency>
                <groupId>net.sf.ehcache</groupId>
                <artifactId>ehcache</artifactId>
                <version>2.10.4</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-ehcache -->
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-ehcache</artifactId>
                <version>5.2.12.Final</version>
            </dependency>
    ehcache需要的jar节点

        注意事项:注意hibernate的核心jar和hibernate-ehcache的jar版本号尽可能的保持一致,还有如果使用高版本的hibernate的话ehcache版本太低不合适

        hibernate的jar包版本在4.0之前和之后有一个本质的区别,就是配置的区别,我会在后面配置到的时候会讲的

      2.ehcache.xml的配置

    <?xml version="1.0" encoding="UTF-8"?>
    <ehcache>
        <!-- 默认的临时文件-->
        <diskStore path="java.io.tmpdir"/>
        <!--
        maxElementsInMemory:在内存中对象最大保存数量
        eternal:是否永久不销毁
        timeToIdleSeconds:最大空闲时间
        timeToLiveSeconds:最大存活时间
        overflowToDisk:内存溢出是否保存到磁盘
    
         memoryStoreEvictionPolicy  缓存清理策略
        1 FIFO first in first out ,先进先出
        2 LFU  Less Frequently Used ,最少被使用的
        2 LRU  Least Recently Used ,最近最少使用的,缓存的元素有一个时间戳,
        当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,
        那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
        -->
        <defaultCache
                maxElementsInMemory="10000"
                eternal="false"
                timeToIdleSeconds="120"
                timeToLiveSeconds="120"
                overflowToDisk="true"
                memoryStoreEvictionPolicy="LRU"
        />
    </ehcache>

      3.集成到hibernate.cfg.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
        <session-factory>
            <!--jdbc连接四要素-->
            <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
            <property name="hibernate.connection.url">jdbc:mysql:///y2167</property>
            <property name="hibernate.connection.username">root</property>
            <property name="hibernate.connection.password"></property>
    
            <!--在控制台上展示sql-->
            <property name="show_sql">true</property>
    
            <!--格式化sql-->
            <!--<property name="format_sql">true</property>-->
    
            <!--====================================================================-->
    
            <!--ddl操作生成策咯,每次运行都在原有表上修改,没有的话就创建表-->
            <!--
            <property name="hbm2ddl.auto"></property>
            key - hbm2ddl.auto:自动生成表结构策略
            value - update(使用最多):当数据库不存在表时,hibernate启动后会自动生成表结构。
                 当数据库表存在时,如果一样,则只会写入数据,不会改变表结构。
                 当数据库表存在时,如果不一样,则会修改表结构,原有的表结构不会改变。
         create(很少):无论表结构是否存在,hibernate启动后都会重新生成表结构。(造成之前的数据丢失)
         create-drop(极少):无论表结构是否存在,hibernate启动都会重新生成表结构。并且hibernate关闭后,表结构会被删除。来无影去无踪。
         validate(很少):不会创建表结构,不会修改表结构。校验与数据库中的表结构是否一样,如果不一样则报异常。
            -->
            <property name="hbm2ddl.auto">update</property>
    
         <!--重点关注此处!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-->
            <!--开启hibernate需要的2级缓存-->
            <!-- 开启二级缓存 -->
            <property name="hibernate.cache.use_second_level_cache">true</property>
            <!-- 开启查询缓存 -->
            <property name="hibernate.cache.use_query_cache">true</property>
            <!-- 高速缓存提供程序 -->
            <!-- Hibernate4.0 以前使用该设置<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop>-->
            <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</property>
          <!--重点关注此处!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-->

    <!--使用getCurrentSession()需要配置此标签--> <property name="current_session_context_class">thread</property> <!--与小配置文件映射--> <mapping resource="cn/dawn/day05/dao/Dept.hbm.xml"></mapping> <mapping resource="cn/dawn/day05/dao/Emp.hbm.xml"></mapping> </session-factory> </hibernate-configuration>

        正如我上面所展示的,4.0版本之前和之后,配置的方式不同

      4.使用到二级缓存的hbm.xml小配置中配置一行代码 

    <cache usage="read-only"/>

        它的位置在class节点下,id节点之前,我把完整的给合起来

    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="cn.dawn.day05.entity">
        <!--如果上面指定package的话,class的name就不必写全类名-->
        <!--lazy:是否懒加载(延迟加载)        默认值是true,延迟加载-->
        <!--<class name="Teacher">-->
        <!--直接加载-->
        <class name="Dept" lazy="false">
            <!--配置使用2级缓存的策略
            usage:使用的缓存清理策略
            include:是否缓存延迟加载的对象
                   01.all:缓存所有对象
                   02.non-lazy:不缓存延迟加载的对象
            -->
            <cache usage="read-only"/>
    
            <!--主键-->
            <id name="deptId" column="deptId">
                <!--主键生成策咯  assigned程序员自己创建-->
                <!--identity是mysql里的自增,一会做增加操作不必再给主键赋值-->
                <!--increment是先查最大的主键列,在下一条给主键加一-->
                <!--sequence是oracle的主键生成策咯,他一会需要指定序列名字<param name="sequence">序列名</param>-->
                <generator class="assigned"></generator>
            </id>
            <property name="name"/>
            <property name="location"/>
            <!--table指的是中间表,承载关联关系的表-->
            <set name="emps" cascade="all" inverse="true">
                <key>
                    <!--本类表的id-->
                    <column name="deptNo"/>
                </key>
                <!--另外与他有多对多关联的实体类-->
                <one-to-many class="Emp"/>
            </set>
        </class>
    </hibernate-mapping>
    hbm.xml中配置cache的位置参考

    三,二级缓存的测试方法

      1.测试是否配通,二级缓存存在性的证明

        理论就是查一遍,干掉一级缓存,再查一遍,看看sql语句的数量就能明白二级缓存起没起作用

        @Test
        /*
        * 二级缓存存在性的证明
        * 清空一级缓存,看看发几条sql语句
        * */
        public void t1CheckHasCacheTwo(){
            Dept dept = session.get(Dept.class, 1);
            session.clear();
            dept=session.get(Dept.class,1);
    
            /*
            Hibernate: select dept0_.deptId as deptId1_0_0_, dept0_.name as name2_0_0_, dept0_.location as location3_0_0_ from Dept dept0_ where dept0_.deptId=?
            * */
        }

      2.在二级缓存中设置readonly

        对象将不可修改

        @Test
        /*
        * 验证2级缓存策略  当为usage="read-only"的时候
        *
        * 会引发异常:UnsupportedOperationException: Can't write to a readonly object
        * 无法修改只读的对象
        * */
        public void t2ChcheTwoUsageReadOnly(){
            Dept dept = session.get(Dept.class, 1);
            dept.setName("你让我修改一下又不会死");
            tr.commit();
    
            /*
            Hibernate: select dept0_.deptId as deptId1_0_0_, dept0_.name as name2_0_0_, dept0_.location as location3_0_0_ from Dept dept0_ where dept0_.deptId=?
            Hibernate: update Dept set name=?, location=? where deptId=?
    
            java.lang.UnsupportedOperationException: Can't write to a readonly object
            * */
        }

      3.设置二级缓存的模式setCacheModel

        配置二级缓存的模式,就可以指定他在什么时候起作用

        @Test
        /**
         *  设置2级缓存的模式
         *
         *  NORMAL  : 和2级缓存关联,可读可写
         *  IGNORE  : 不和2级缓存关联
         *  GET     : 和2级缓存关联,只读
         *  PUT     : 和2级缓存关联,只写
         *  REFRESH :和2级缓存关联,只写
         *  REFRESH可以设置强行和数据库同步
         *  在核心配置文件中配置下面的属性即可
         *  hibernate.cache.use_minimal_puts
         */
        public void t3CacheMode(){
            Dept dept = session.get(Dept.class, 1);
            /*部门信息一条sql*/
            session.clear();
            /*一级缓存被清除*/
            session.setCacheMode(CacheMode.PUT);/*二级缓存只能写不能读取*/
            dept = session.get(Dept.class, 1);
    
            /*当为PUT的时候,不会查二级缓存了,一级缓存又没有,所以有sql语句查数据库
            Hibernate: select dept0_.deptId as deptId1_0_0_, dept0_.name as name2_0_0_, dept0_.location as location3_0_0_ from Dept dept0_ where dept0_.deptId=?
            Hibernate: select dept0_.deptId as deptId1_0_0_, dept0_.name as name2_0_0_, dept0_.location as location3_0_0_ from Dept dept0_ where dept0_.deptId=?
            * */
        }

    作者:晨曦Dawn

    转载请注明出处,博客地址:https://www.cnblogs.com/DawnCHENXI/p/9141734.html

    如果上方博客有错误,请您指出,感激不尽!!!!!!!!!!!!!!!!!!!!!!!

  • 相关阅读:
    REGIONAL SCRUM GATHERING(RSG)2019 CHINA.
    《敏捷革命》读书笔记
    敏捷之旅2017年北京站活动圆满结束
    团队合作的Ground Rules
    开发团队(Team)的主要职责和特征
    敏捷之旅2017年北京站的活动主题和讲师话题征集中
    产品负责人(Product Owner)的主要职责和技能
    战地记者也在使用Scrum
    Scrum由来
    他们是今年最可爱的人——敏捷之旅2017年北京活动志愿者
  • 原文地址:https://www.cnblogs.com/DawnCHENXI/p/9141734.html
Copyright © 2011-2022 走看看