`
iamcrzay
  • 浏览: 57954 次
  • 性别: 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个类 :
   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类设置缓存):
   	<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 配置文件:
<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>


测试用例:       
     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);
 	   }
   }
}



 
 
---------------------------------------------------------------------
在运新单元测试之前请初始化数据 初始化数据类 请参照前一篇文章的的 InitialData类
运行了以上的单元测试 我们可以对hibernate的二级缓存 就会有个比较清晰的认识
分享到:
评论

相关推荐

    Hibernate二级缓存

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

    hibernate 二级缓存详解

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

    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关闭时...

    Hibernate二级缓存(Ehcache)

    【标题】:“Hibernate二级缓存(Ehcache)” 【正文】: Hibernate是一个流行的Java对象关系映射(ORM)框架,它允许开发者用面向对象的方式来处理数据库操作。然而,随着应用规模的扩大,性能优化变得至关重要,...

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

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

Global site tag (gtag.js) - Google Analytics