• Hibernate(十六):Hibernate二级缓存


    • Hibernate缓存

    缓存(Cache):计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如磁盘上的文件或者数据库)之间,起作用是降低应用程序直接读取永久性数据存储源的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的拷贝。缓存的物理介质通常是内存。

    Hibernate中提供了两个级别的缓存

    1)第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存。这一级别的缓存由hibernate管理。

    测试函数1:Hibernate一级缓存示例

    1     @Test
    2     public void testHibernateCacheLevel1() {
    3         Department depart0 = (Department) session.get(Department.class, 1);
    4         System.out.println(depart0);
    5         
    6         Department depart1 = (Department) session.get(Department.class, 1);
    7         System.out.println(depart1);
    8     }
    View Code

    执行sql及结果:

     1 Hibernate: 
     2     select
     3         department0_.ID as ID1_0_0_,
     4         department0_.NAME as NAME2_0_0_ 
     5     from
     6         DX_DEPARTMENT department0_ 
     7     where
     8         department0_.ID=?
     9 Department [id=1, name=开发部门]
    10 
    11 Department [id=1, name=开发部门]
    View Code

    测试函数2:Hibernate一级缓存是事务级别证明

     1     @Test
     2     public void testHibernateCacheLevel1_Transaction() {
     3         Department depart0 = (Department) session.get(Department.class, 1);
     4         System.out.println(depart0);
     5         
     6         transaction.commit();
     7         session.close();
     8         session = sessionFactory.getCurrentSession();
     9         transaction = session.beginTransaction();
    10         
    11         Department depart1 = (Department) session.get(Department.class, 1);
    12         System.out.println(depart1);
    13     }
    View Code

    执行sql及结果:

     1 Hibernate: 
     2     select
     3         department0_.ID as ID1_0_0_,
     4         department0_.NAME as NAME2_0_0_ 
     5     from
     6         DX_DEPARTMENT department0_ 
     7     where
     8         department0_.ID=?
     9 Department [id=1, name=开发部门]
    10 
    11 Hibernate: 
    12     select
    13         department0_.ID as ID1_0_0_,
    14         department0_.NAME as NAME2_0_0_ 
    15     from
    16         DX_DEPARTMENT department0_ 
    17     where
    18         department0_.ID=?
    19 Department [id=1, name=开发部门]
    View Code

    备注:

    本章节所涉及到的demo工程是基于Hibernate(十二):HQL查询(一)所创建的工程基础上进行测试。

    2)第二级别的缓存是SesssionFactory级别的缓存,它是属于进程范围的缓存。

    • SessionFactory级别的缓存

    SesssionFactory的缓存可以分为两类

    1)内置缓存:Hibernate自带的,不可卸载。通常在Hibernate的初始化阶段,Hibernate会把映射元数据和预定义的SQL语句放到SessionFactory的缓存中,映射元数据是映射文件中数据(.hbm.xml文件中的数据)的赋值,该内置缓存是只读的。

    2)外置缓存(二级缓存):一个可配置的缓存插件。在默认情况下,SessionFactory不会启用这个缓存插件。外置缓存中的数据是数据库数据的复制,外置缓存的物理介质可以是内存或硬盘。

    • Hibernate二级缓存的适用范围

    1)适合放入二级缓存的数据:

      很少被修改

      不是很重要的数据,允许出现偶尔的并发问题

    2)不适合放入二级缓存中的数据

      经常被修改

      财务数据,绝对不允许出现并发问题

      与其他应用程序共享的数据

    • Hibernate二级缓存架构图

    • 二级缓存的并发访问策略

    1)两个并发的事务同时访问持久层的缓存的相同数据时,也有可能出现各类并发问题。

    2)二级缓存可以设定以下4种类型的并发访问策略,每一种访问策略对应一种事务隔离界别:

      √ 非严格读写(Nonstrict-read-write):不保证缓存与数据库中数据一致性。提供Read Uncommited 事务隔离级别,对于极少被修改,而且允许脏读的数据可以采用该策略。

      √ 读写型(Read-write):提供Read Commited事务隔离级别。对于经常读但是很少被修改的数据,可以采用该隔离类型,因为它可以防止脏读。

      √ 事务型(Transactional):仅在受管理环境下适用,它提供了Repeateable Read事务隔离级别。对于经常读但很少被修改的数据,可以采用这种隔离策略,应为它可以防止脏读和不可重复读。

      √ 只读型(Read-Only):提供Serializable数据隔离级别,对于从来不会被修改的数据,可以采用这种访问策略。

    • 管理Hibernate的二级缓存

    1)Hibernate的二级缓存是进程或集群分为内的缓存

    2)二级缓存是可配置的插件,Hibernate允许选用选用以下类型的缓存插件:

      √ EHCache:可作为进程范围内存的缓存,存放数据的物理介质可以使用内存或磁盘,对Hibernate查询缓存提供了支持。

      √ OpenSymphony OSCahce:可以作为内存范围内的缓存,存放数据的物理介质可以使用内存或硬盘,提供了丰富的缓存数据过期策略,对Hibernate的查询缓存提供了支持。

      √ SwarmCache:可以作为集群范围内的缓存,但不支持Hibernate的查询缓存。

      √ JBoosCache:可作为集群范围内的缓存,支持Hibernate的查询缓存。

    4种缓存插件支持的并发访问策略:

    • EHCache的使用:

    步骤一:添加EHCache需要的jar包

    找到hibernate开发路径hibernate-release-5.2.9.Finalliboptionalehcache下的所有jar,导入到工程。

    步骤二:拷贝ehcache.xml文件到src下

    拷贝hibernate-release-5.2.9.Finalprojectetcehcache.xml文件到src下

    步骤三:通过配置hibernate.cfg.xml文件启用hibernate二级缓存,并指定二级缓存的实现类

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <!DOCTYPE hibernate-configuration PUBLIC
     3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
     4         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
     5 <hibernate-configuration>
     6     <session-factory>
     7             。。。
     8         <!-- 启用二级缓存 -->
     9         <property name="hibernate.cache.use_second_level_cache">true</property>
    10         <!-- 配置二级缓存使用的插件 -->
    11         <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
    12             。。。
    13     </session-factory>
    14 </hibernate-configuration>

    步骤四:在hibernate.cfg.xml或者Department.hbm.xml中配置,针对Department启用二级缓存。

    1)通过配置hibernate.cfg.xml启用Department类的二级缓存

    <?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>
            。。。        
            <!-- 启用二级缓存 -->
            <property name="hibernate.cache.use_second_level_cache">true</property>
            <!-- 配置二级缓存使用的插件 -->
            <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
    
            <mapping resource="com/dx/hibernate09/hql01/Department.hbm.xml" />
            <mapping resource="com/dx/hibernate09/hql01/Employee.hbm.xml" />
                    
            <class-cache usage="read-write" class="com.dx.hibernate09.hql01.Department"/>
        </session-factory>
    </hibernate-configuration>

    2)通过配置Department.hbm.xml来启用Department类的二级缓存

     1 <?xml version="1.0"?>
     2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     4 <!-- Generated 2017-6-9 23:13:49 by Hibernate Tools 3.5.0.Final -->
     5 <hibernate-mapping>
     6     <class name="com.dx.hibernate09.hql01.Department" table="DX_DEPARTMENT">
     7         <cache usage="read-write" />
     8 
     9         <id name="id" type="java.lang.Integer">
    10             <column name="ID" />
    11             <generator class="native" />
    12         </id>
    13         <property name="name" type="java.lang.String">
    14             <column name="NAME" />
    15         </property>
    16 
    17         <set name="employees" table="DX_EMPLOYEE" inverse="true" lazy="true">
    18             <key>
    19                 <column name="DEPARTMENT_ID" />
    20             </key>
    21             <one-to-many class="com.dx.hibernate09.hql01.Employee" />
    22         </set>
    23     </class>
    24 </hibernate-mapping>

    测试代码:

     1     @Test
     2     public void testHibernateCacheLevel1_Transaction() {
     3         Department depart0 = (Department) session.get(Department.class, 1);
     4         System.out.println(depart0);
     5         
     6         transaction.commit();
     7         session.close();
     8         session = sessionFactory.getCurrentSession();
     9         transaction = session.beginTransaction();
    10         
    11         Department depart1 = (Department) session.get(Department.class, 1);
    12         System.out.println(depart1);
    13     }

    执行sql及结果:

     1 Hibernate: 
     2     select
     3         department0_.ID as ID1_0_0_,
     4         department0_.NAME as NAME2_0_0_ 
     5     from
     6         DX_DEPARTMENT department0_ 
     7     where
     8         department0_.ID=?
     9 Department [id=1, name=开发部门]
    10 
    11 Department [id=1, name=开发部门]
  • 相关阅读:
    hdu 4970 树状数组 “改段求段”
    hdu 2242 无向图/求用桥一分为二后使俩个bcc点权值和之差最小并输出 /缩点+2次新图dfs
    hdu3715 2-sat+二分
    hdu 3639 有向图缩点+建反向图+搜索
    hdu 3072 有向图缩点成最小树形图计算最小权
    hdu 3061 hdu 3996 最大权闭合图 最后一斩
    hdu 3879 hdu 3917 构造最大权闭合图 俩经典题
    hdu 4738 无向图缩点断桥 // 细节坑题
    hdu3452 无向树去掉最小的边集使任何叶子与根不连通 / 最小割
    hdu 3657 最小割的活用 / 奇偶方格取数类经典题 /最小割
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/7000254.html
Copyright © 2020-2023  润新知