zoukankan      html  css  js  c++  java
  • Hibernate缓存

    Hibernate缓存在工作面试的时候很可能会遇到的问题。

    缓存其实就是一块内存空间,充当数据库的内存中的一个临时的容器。

    一:hibernate缓存是怎样的?

       Hibernate缓存提供了两种缓存:一级缓存和二级缓存。

    1 一级缓存又称事务级缓存,Session的缓存。

        在Hibernate中一级缓存存是基于Session的生命周期实现的,每一个Session会在内部维护一个数据缓存,她随着Session的创建而创建,销毁而销毁。

        一级缓存是必须的,在同一个一级缓存中,每一个持久化类的对象都是唯一的(都有唯一的OID)。   

    2 二级缓存又称应用级缓存 SessionFactory的缓存 。

       在Hibernate中二级级缓存是由SessionFactory实现,所有用一个SessionFactory创建的Session对象共享此缓存。

       由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此Hibernate二级缓存是进程范围或者集群范围的缓存,有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。 

      第二级缓存是可选的,是一个可配置的插件,默认下SessionFactory不会启用这个插件。

    什么样的数据适合存放到第二级缓存中?   
      1) 很少被修改的数据   
      2) 不是很重要的数据,允许出现偶尔并发的数据   
      3) 不会被并发访问的数据   
      4) 常量数据   
    不适合存放到第二级缓存的数据?   
      1) 经常被修改的数据   
      2) 绝对不允许出现并发访问的数据,  
      3) 与其他应用共享的数据。

     

    二:为什么我们要使用Hibernate缓存?

                Hibernate就是对JDBC进行的封装 带来的就是数据访问效率的降低,和性能的下降 对于Hibernate这类ORM而言,缓存显的尤为重要,它是持久层性能提升的关键。

        1 Hibernate是一个持久层框架,经常访问物理数据库。

      2 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能。

      3 缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。

    三:怎样使用hibernate缓存?

     二级缓存:

    1 开始缓存:

    为了开启二级缓存,需要在hibernate.cfg.xml文件中配置如下属性:

    1 <!-- 开启二级缓存 -->
    2         <property name="cache.use_second_level_cache">true</property>

    一旦开启了二级缓存,并设置了对某个持久化实体类启动缓存,SessionFactory就会缓存应用访问过的该实体类的每个对象,除非缓存的数据超出缓存空间。

    2 在实际应用中,一般不需要开发者自己实现缓存,直接使用第3方提供的开源缓存实现即可。因此在hibernate.cfg.xml文件中设置开启缓存后,还需要设置使用哪种缓存实现类。配置如下:

    1 <!-- 设置二级缓存的实现类 -->
    2         <property name="cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

    需要注意的是:

    3 实际上在项目中使用EHCache缓存实现,仅仅复制liboptional下对应缓存的JAR包还不够,应用EHCache还需要依赖于commons-logging.jar,backport-util-concurrent.jar两个工具包。

    4 将缓存实现所需要的配置文件添加到系统的类加载路径中,对于EHCache缓存,它还需要一个ehcache.xml配置文件:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <ehcache>
     3     <diskStore path="D:/path"/>       <!-- 启用磁盘缓存的位置-->
     4     <defaultCache
     5         maxElementsInMemory="10000"
     6         eternal="false"
     7         timeToIdleSeconds="120"
     8         timeToLiveSeconds="120"
     9         overflowToDisk="true"
    10         />
    11         <!-- maxElementsInMemory 设置缓存中最多可放多少个对象 -->
    12         <!-- eternal 设置缓存是否永久有效 -->
    13         <!-- timeToIdleSeconds 设置缓存的对象多少秒没有被使用就会清理掉 -->
    14         <!-- timeToLiveSeconds 设置缓存的对象在销毁之前可以缓存多少秒 -->
    15         <!-- overflowToDisk 设置当内存中缓存的记录达到maxElementsInMemory 时是否被持久化到硬盘中,保存路径由<diskStore../>元素指定 -->
    16 </ehcache>

    5 在实体的缓存策略放在不同的映射文件中分别管理:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <!DOCTYPE hibernate-mapping PUBLIC 
     3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
     5     
     6     <hibernate-mapping>
     7     
     8     <class name="com.cy.beans.Author" table="t_author" catalog="j2ee">   <!-- catalog数据库 -->
     9       <!-- 设置缓存策略 -->
    10         <cache usage="read-only"/>  <!--   这里-->
    11      
    12               <id name="id" type="java.lang.Long"><!-- 此行的ID,为对象的属性ID -->
    13                   <column name="id"></column><!-- 此行的ID,为表字段ID -->
    14                   <generator class="increment"></generator><!-- 给id指定生成策略 -->
    15               </id>
    16     
    17               <property name="authorName" type="java.lang.String">
    18                  <column name="authorName"></column>
    19               </property>
    20               
    21          <!--lazy :lazy是延时的意思,如果lazy=true,那么就是说数据库中关联子表的信息在hibernate容器启动的时候不会加载,而是在你真正的访问到字表非标识字段的时候,才会去加载。
    22                                                 反之,如果lazy=false的话,就是说,子表的信息会同主表信息同时加载  
    23                    Hibernate3.x,lazy默认是true;
    24                    -->
    25          <!-- inverse:hibernate双向关系中的基本概念。inverse的真正作用就是指定由哪一方来维护之间的关联关系。当一方中指定了“inverse=false”(默认),那么那一方就有责任负责之间的关联关系 -->
    26         
    27     <set name="books" table="t_book" cascade="all" inverse="true" lazy="false"><!-- set映射节点 -->
    28              <key column="fk_author_id"></key><!-- 外键 -->
    29              <one-to-many class="com.cy.beans.Book"/><!--one-to-mang节点  -->
    30     </set>
    31     </class>
    32      
    33     </hibernate-mapping>

    缓存同步策略决定了数据对象在缓存中的存取规则.Hibernate中提供了4种不同的缓存同步策略

    - read-only:只读.对于不会发生改变的数据可使用

    - nonstrict-read-write:如果程序对并发访问下的数据 同步要求不 严格,且数据更新频率较低,采用本缓存 同步策略可获得较 好性能

    - read-write:严格的读写缓存.基于时间戳判定机制,实现了“read committed”事务隔离等级.用于对数据同步要求的情况,但支持分布式缓存,实际应用中使用最多的缓存同步策略.

    - transactional:事务型缓存,必须运行在JTA事务环境中.此缓存中, 缓存的相关操作被添加到事务中,如事务失败,则缓冲池的数据 会一同回滚到事务的开始之前的状态.事务型缓存实现了 “Repeatable read”事务隔离等级,有效保证了数据的合法性, 适应于对关键数据的缓存,Hibernate内置缓存中,只有 JBossCache支持事务型缓存.

  • 相关阅读:
    面试准备
    论文投稿Cover letter
    Pycharm 快捷键
    linux下常用命令:
    Qt中数据模块学习
    Qt 多线程和网络编程学习
    VS高效开发快捷键
    良好编码风格习惯整理
    Qt QAxObject操作excel文件过程总结(转):
    Qt开发中的实用笔记三--关于各种类的零碎知识点:
  • 原文地址:https://www.cnblogs.com/hellokitty1/p/5052899.html
Copyright © 2011-2022 走看看