`
yy_dan
  • 浏览: 64526 次
  • 性别: Icon_minigender_1
  • 来自: 湖南岳阳
最近访客 更多访客>>
社区版块
存档分类
最新评论

Hibernate的二级缓存

阅读更多

Hibernate二级缓存:
   二级缓存也称位进程级缓存或者sessionFactory级缓存,二级缓存可以被所有的session共享
 
  二级缓存的配置和使用: 
      将echcache.xml(这个文件在hibernate代码包中的etc 目录下)拷贝到src目录下 
      开启二级缓存 修改hibernate.cfg.xml文件
         <property name="hibernate.cache.use_second_level_cache">true</property> 
      指定缓存产品提供商,修改hibernate.cfg.xml文件
        <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> 
      指定哪些类使用二级缓存: 
          在映射文件中采用<cache usage=""> 标签 
         在hibernate.cfg.xml中配置
           <class-cache class="com.june.hibernate.Student" usage="read-only"/> 
           我推荐优先使用<read-only> 
          1.  <read-only> 
                如果你的应用程序只需读取一个持久化类的实例,而无需对其修改, 那么就可以对其进行只读 缓存。这是最简单,也是实用性最好的方法。甚至在集群中,它也能完美地运作。
          2.  read/write

                  如果应用程序需要更新数据,那么使用读/写缓存 比较合适。 如果应用程序要求“序列化事务”的隔离级别(serializable transaction isolation level),    那么就决不能使用这种缓存策略。如果在JTA环境中使用缓存,你必须指定hibernate.transaction.manager_lookup_ class属性的值,  通过它,Hibernate才能知道该应用程序中JTA的TransactionManager的具体策略。 在其它环境中,你必须保证在Session.close()  、或Session.disconnect()调用前, 整个事务已经结束。 如果你想在集群环境中使用此策略,你必须保证底层的缓存实现支持锁定(locking)。Hibernate  内置的缓存策略并不支持锁定功能
          3. nonstrict read/write
               如果应用程序只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离, 那么比较适合使用非严格读/写 缓存策略。如果在JTA环境中使用该策略, 你必须为其指定hibernate.transaction.manager_lookup_class属性的值, 在其它环境中,你必须保证在  Session.close()、或Session.disconnect()调用前, 整个事务已经结束 
           
  二级缓存的是缓存实体对象的:
     了解一级缓存的交互(session.setCacheMode())
       主要是 CacheMode.NORMAL
            CacheMode.PUT
            CacheMode.GET
             具体常见HibernateReference       
有如下2个类 :

Java代码 :
  1. public class Clazz {   
  2. private Integer id;   
  3. private String name;   
  4. private Set<Student> students=new HashSet<Student>();   
  5.  }   
  6. public class Student {   
  7. private Integer id;   
  8. private String name;   
  9. private Clazz clazz;   
   public class Clazz {
   private Integer id;
   private String name;
   private Set<Student> students=new HashSet<Student>();
    }
   public class Student {
   private Integer id;
   private String name;
   private Clazz clazz;
}



映射文件为(我们对students类设置缓存):

Xml代码:
  1.     <class name="com.june.hibernate.Clazz" table="t_clazz">  
  2.    <id name="id">  
  3.        <generator class="native"></generator>  
  4.    </id>  
  5.    <property name="name"></property>       
  6.    <set name="students" inverse="true">  
  7.       <key column="clazz"/>  
  8.       <one-to-many class="com.june.hibernate.Student"/>  
  9.    </set>    
  10. </class>  
  11. <class name="com.june.hibernate.Student" table="t_student">  
  12.    <!--    
  13.    <cache usage="read-only"/>-->  
  14.    <id name="id">  
  15.        <generator class="native"></generator>  
  16.    </id>  
  17.    <property name="name"></property>       
  18.    <many-to-one name="clazz" cascade="save-update"></many-to-one>    
  19. </class>  
   	<class name="com.june.hibernate.Clazz" table="t_clazz">
	   <id name="id">
	       <generator class="native"></generator>
	   </id>
	   <property name="name"></property>	
	   <set name="students" inverse="true">
	      <key column="clazz"/>
	      <one-to-many class="com.june.hibernate.Student"/>
	   </set> 
	</class>
	<class name="com.june.hibernate.Student" table="t_student">
	   <!--  
	   <cache usage="read-only"/>-->
	   <id name="id">
	       <generator class="native"></generator>
	   </id>
	   <property name="name"></property>	
	   <many-to-one name="clazz" cascade="save-update"></many-to-one> 
	</class>


Hibernate 配置文件:

Xml代码:
  1. <hibernate-configuration>  
  2.     <session-factory>  
  3.     <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>  
  4.     <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_cache_level_2</property>  
  5.     <property name="hibernate.connection.username">root</property>  
  6.     <property name="hibernate.connection.password">123456</property>  
  7.     <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>  
  8.     <property name="hibernate.show_sql">true</property>  
  9.     <!-- 开启二级缓存 hibernate默认就是开启的 -->  
  10.     <property name="hibernate.cache.use_second_level_cache">true</property>  
  11.     <!-- 指定缓存产品提供商 -->  
  12.     <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>  
  13.      <mapping resource="com/june/hibernate/Clazz.hbm.xml"/>  
  14.      <mapping resource="com/june/hibernate/Student.hbm.xml"/>  
  15.      <!-- 我推荐在此设置二级缓存 而不是在具体的类配置文件中设置 因为在此设置会对非常清楚的了解 那些是设了二级缓存的 那些是没有设的-->  
  16.      <class-cache class="com.june.hibernate.Student" usage="read-only"/>  
  17.     </session-factory>  
  18. </hibernate-configuration>  
<hibernate-configuration>
	<session-factory>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_cache_level_2</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">123456</property>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.show_sql">true</property>
    <!-- 开启二级缓存 hibernate默认就是开启的 -->
    <property name="hibernate.cache.use_second_level_cache">true</property>
    <!-- 指定缓存产品提供商 -->
    <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
     <mapping resource="com/june/hibernate/Clazz.hbm.xml"/>
     <mapping resource="com/june/hibernate/Student.hbm.xml"/>
     <!-- 我推荐在此设置二级缓存 而不是在具体的类配置文件中设置 因为在此设置会对非常清楚的了解 那些是设了二级缓存的 那些是没有设的-->
     <class-cache class="com.june.hibernate.Student" usage="read-only"/>
	</session-factory>
</hibernate-configuration>


测试用例:       

Java代码    
package com.june.hibernate;
import junit.framework.TestCase;
import org.hibernate.CacheMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
public class CacheLevel2Test extends TestCase{
 /**
  * 开启2个session分别调用load
  */
    public void testLoad(){
      Session session=null;
        Transaction tx=null;
      try{
       //第一个session
       session=HibernateUtil.getSession();
       tx=session.beginTransaction();
       Student student1=(Student)session.load(Student.class,1);
       System.out.println("student1.name="+student1.getName());
     
       tx.commit();
      }catch(Exception e){
       e.printStackTrace();
       tx.rollback();
      }finally{
       HibernateUtil.colseSession(session);
      }
      
    try{
     //第二个session
       session=HibernateUtil.getSession();
       tx=session.beginTransaction();
       Student student1=(Student)session.load(Student.class,1);
       //不会发出session 因为开启了二级缓存 session共享二级缓存
       // load()方法也使用二级缓存
       System.out.println("student1.name="+student1.getName());
     
       tx.commit();
      }catch(Exception e){
       e.printStackTrace();
       tx.rollback();
      }finally{
       HibernateUtil.colseSession(session);
      }
    }
 /**
  * 开启2个session分别调用get()
  */
    public void testGet(){
      Session session=null;
        Transaction tx=null;
      try{
       //第一个session
       session=HibernateUtil.getSession();
       tx=session.beginTransaction();
       Student student1=(Student)session.get(Student.class,1);
       System.out.println("student1.name="+student1.getName());
     
       tx.commit();
      }catch(Exception e){
       e.printStackTrace();
       tx.rollback();
      }finally{
       HibernateUtil.colseSession(session);
      }
      
    try{
     //第二个session
       session=HibernateUtil.getSession();
       tx=session.beginTransaction();
       Student student1=(Student)session.get(Student.class,1);
       //也不会发出session 因为开启了二级缓存 session共享二级缓存
       //get()也使用二级缓存
       System.out.println("student1.name="+student1.getName());
     
       tx.commit();
      }catch(Exception e){
       e.printStackTrace();
       tx.rollback();
      }finally{
       HibernateUtil.colseSession(session);
      }
    }
 /**
  * 开启2个session分别调用load 用sessionFactory 清除二级缓存
  */
    public void testLoad2(){
      Session session=null;
        Transaction tx=null;
      try{
       //第一个session
       session=HibernateUtil.getSession();
       tx=session.beginTransaction();
       Student student1=(Student)session.load(Student.class,1);
       System.out.println("student1.name="+student1.getName());
     
       tx.commit();
      }catch(Exception e){
       e.printStackTrace();
       tx.rollback();
      }finally{
       HibernateUtil.colseSession(session);
      }
       SessionFactory factory=HibernateUtil.getSessionFactory();
       //管理二级缓存
       //factory.evict(Student.class,1);
       factory.evict(Student.class);
    try{
     //第二个session
       session=HibernateUtil.getSession();
       tx=session.beginTransaction();
       Student student1=(Student)session.load(Student.class,1);
       //会发出查询sql 主要是由于二级缓存中的数据被清楚啦
       System.out.println("student1.name="+student1.getName());
     
       tx.commit();
      }catch(Exception e){
       e.printStackTrace();
       tx.rollback();
      }finally{
       HibernateUtil.colseSession(session);
      }
    }
    /**
  * 一级缓存和二级缓存的交互
  * 默认为CacheMode.NORMAL
  * 即以及缓存即向二级缓存中写数据也从二级缓存中读数据
  */
    public void testCache(){
      Session session=null;
        Transaction tx=null;
      try{
     //第一个session
       session=HibernateUtil.getSession(); 
       tx=session.beginTransaction();
       Student student1=(Student)session.load(Student.class,1);
       System.out.println("student1.name="+student1.getName());
       tx.commit();
      }catch(Exception e){
       e.printStackTrace();
       tx.rollback();
      }finally{
       HibernateUtil.colseSession(session);
      }
      try{
     //第2个session
       session=HibernateUtil.getSession();
       //仅从二级缓存读数据 而不从二级缓存写数据
       session.setCacheMode(CacheMode.GET);
       tx=session.beginTransaction();
       Student student1=(Student)session.load(Student.class,1);
       //不会发出sql 语句
       System.out.println("student1.name="+student1.getName());   
       tx.commit();
      }catch(Exception e){
       e.printStackTrace();
       tx.rollback();
      }finally{
       HibernateUtil.colseSession(session);
      }
       SessionFactory factory=HibernateUtil.getSessionFactory();
   
    try{
     //第3个session
       session=HibernateUtil.getSession();     
       tx=session.beginTransaction();
       Student student1=(Student)session.load(Student.class,1);
      //  因为session设置了CacheMode位GET 所以二级缓存中没有数据
       System.out.println("student1.name="+student1.getName());    
       tx.commit();
      }catch(Exception e){
       e.printStackTrace();
       tx.rollback();
      }finally{
       HibernateUtil.colseSession(session);
      }
    }
    public void testCache2(){
     Session session=null;
       Transaction tx=null;
     try{
    //第一个session
      session=HibernateUtil.getSession(); 
      tx=session.beginTransaction();
      Student student1=(Student)session.load(Student.class,1);
      System.out.println("student1.name="+student1.getName());
      tx.commit();
     }catch(Exception e){
      e.printStackTrace();
      tx.rollback();
     }finally{
      HibernateUtil.colseSession(session);
     }
     try{
    //第2个session
      session=HibernateUtil.getSession();
      //仅从二级缓写读数据 而不从二级缓读写数据
      session.setCacheMode(CacheMode.PUT);
      tx=session.beginTransaction();
      Student student1=(Student)session.load(Student.class,1);
      System.out.println("student1.name="+student1.getName());   
      tx.commit();
     }catch(Exception e){
      e.printStackTrace();
      tx.rollback();
     }finally{
      HibernateUtil.colseSession(session);
     }
      SessionFactory factory=HibernateUtil.getSessionFactory();
  
    try{
     //第3个session
      session=HibernateUtil.getSession();     
      tx=session.beginTransaction();
      Student student1=(Student)session.load(Student.class,1);
     //  因为session设置了CacheMode位GET 所以二级缓存中没有数据
      System.out.println("student1.name="+student1.getName());    
      tx.commit();
     }catch(Exception e){
      e.printStackTrace();
      tx.rollback();
     }finally{
      HibernateUtil.colseSession(session);
     }
   }
}
分享到:
评论

相关推荐

    Hibernate二级缓存

    Hibernate二级缓存是一种提高应用程序性能的技术,它将数据存储在SessionFactory级别的缓存中,使得数据可以在不同的Session之间共享。这与一级缓存(Session级别)不同,一级缓存仅存在于单个Session生命周期内,当...

    hibernate 二级缓存详解

    Hibernate 二级缓存是针对SessionFactory级别的全局缓存,与一级缓存(Session级别)不同,一级缓存只在单个Session生命周期内有效。二级缓存则允许不同Session之间共享数据,提高了数据访问效率,减少了对数据库的...

    hibernate二级缓存

    Hibernate 二级缓存是一种高效的数据存储机制,它能够显著提升Web应用的性能,尤其是在处理大量数据流动时。缓存的主要目标是减少应用与数据库之间的交互次数,从而降低延迟并减轻数据库服务器的压力。在Hibernate...

    Hibernate 二级缓存

    Hibernate 二级缓存

    hibernate二级缓存实例

    在这个"hibernate二级缓存实例"中,我们将深入探讨二级缓存的原理、配置以及在实际项目中的应用。 首先,我们需要了解一级缓存和二级缓存的区别。一级缓存是Session级别的,每个Session都有自己的一级缓存,用于...

    hibernate二级缓存示例源码

    **hibernate二级缓存详解** Hibernate作为Java领域中广泛使用的对象关系映射(ORM)框架,极大地简化了数据库操作。然而,在处理大量数据时,性能优化显得尤为重要,这就是二级缓存的作用。本文将深入探讨Hibernate...

    Hibernate 二级缓存 总结整理

    **Hibernate 二级缓存总结整理** 在Java的持久化框架中,Hibernate是一个广泛使用的ORM(对象关系映射)工具,它极大地简化了数据库操作。在处理大数据量或高并发的场景下,为了提高性能和减少数据库负载,...

    hibernate二级缓存包

    Hibernate二级缓存是Java开发中使用Hibernate框架进行数据持久化时优化性能的一种重要技术。它在一级缓存(Session级别的缓存)的基础上,提供了一个全局的、跨会话的数据存储层,可以显著减少对数据库的访问,从而...

    hibernate二级缓存java包下载

    二级缓存是 Hibernate 缓存策略的一部分,它在应用程序的多个会话之间共享数据,进一步优化了数据库访问效率。 二级缓存分为以下关键知识点: 1. **一级缓存与二级缓存的区别**: - 一级缓存:每个 Hibernate ...

    hibernate 二级缓存

    本篇文章将深入探讨Hibernate二级缓存的概念、工作原理以及如何在实际项目中设置和使用。 **一、二级缓存概念** 一级缓存是每个Hibernate Session内部的一个内存区域,用于存储Session期间的操作对象。当Session...

    hibernate二级缓存所需要的 jar包

    本篇将详细介绍Hibernate二级缓存的概念、作用以及所需jar包的作用。 一、Hibernate二级缓存概念 Hibernate的一级缓存是指Session级别的缓存,每个Session内部都有一个一级缓存,用于存储实体对象,当Session关闭时...

    day37 05-HIbernate二级缓存:一级缓存更新同步到二级缓存及二级缓存配置文件

    本篇文章将深入探讨Hibernate的二级缓存机制,以及如何进行一级缓存与二级缓存的同步,同时还会介绍二级缓存的配置文件设置。 一级缓存是Hibernate默认提供的缓存,每个SessionFactory实例都有一个一级缓存。当对象...

Global site tag (gtag.js) - Google Analytics