28hibernate_cache_level_2

hibernate二级缓存

二级缓存也称进程级的缓存或SessionFactory级的缓存,二级缓存可以被所有的session共享
二级缓存的生命周期和SessionFactory的生命周期一致,SessionFactory可以管理二级缓存

二级缓存的配置和使用:
    * 将echcache.xml文件拷贝到src下:
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
    * 开启二级缓存,修改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>标签:<cache usage="read-only"/>
        * 在hibernate.cfg.xml文件中,采用<class-cache>标签:<class-cache class="com.bjsxt.hibernate.Student" usage="read-only"/>
        
二级缓存是缓存实体对象的

了解一级缓存和二级缓存的交互        
        
                
invalidation n. 失效;无效
replication  n. 复制;回答;反响


package com.bjsxt.hibernate;

import java.io.Serializable;

import org.hibernate.CacheMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import junit.framework.TestCase;

public class CacheLevel2Test extends TestCase {

    /**
     * 开启两个session,分别调用load
     * 测试结果:select ... ...
     
*/
    public void testCache1() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            Student student = (Student)session.load(Student.class1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            //不会发出sql,因为开启了二级缓存,session是共享二级缓存的
            Student student = (Student)session.load(Student.class1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        
    }    
    
    /**
     * 开启两个session,分别调用get
     * 测试结果:select ... ...
     
*/
    public void testCache2() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            Student student = (Student)session.get(Student.class1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            //不会发出sql,因为开启了二级缓存,session是共享二级缓存的
            Student student = (Student)session.get(Student.class1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
    }    
    
    /**
     * 开启两个session,分别调用load,再使用SessionFactory清除二级缓存
     * 测试结果:select ...  select ...
     
*/
    public void testCache3() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            Student student = (Student)session.load(Student.class1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        
        //管理二级缓存
        SessionFactory factory = HibernateUtils.getSessionFactory();
        //factory.evict(Student.class);//清除所有对象
        factory.evict(Student.class1);//清除某一个对象
        
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            //会发出查询sql,因为二级缓存中的数据被清除了
            Student student = (Student)session.load(Student.class1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
    }
    
    
    /**
     * 一级缓存和二级缓存的交互
     * 1、执行load默认会把数据写入二级缓存一份,并且能读出来。
     * 2、设置CacheMode_GET,则只能把数据从二级缓存中读出来,不能写进去一份,此时二级缓存中是没有数据的(二级缓存中没有数据,能读出来)
     * 3、设置CacheMode_PUT,则只能把数据写入二级缓存中一份,此时二级缓存中是有一份数据的,但是却不能把数据从二级缓存中读出来(二级缓存中有数据,读不出来)
      
*/
    
    
    //Test1:先load默认,再load默认
    
//测试结果:select ... ...
    public void testCache4_A_defaultLoad_defaultLoad() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            //向一级缓存和二级缓存中各写入一份
            Student student = (Student)session.load(Student.class1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        //新开一session,清理一级缓存的数据,但是二级缓存中还有数据,再加载的时候直接用二级缓存中的数据
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            Student student = (Student)session.load(Student.class1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }    
    }    
    


    //Test2:先设置load的模式为:CacheMode.GET,再load默认
    
//测试结果:select ... select ...
    public void testCache4_B_CacheModeGET_defaultLoad() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            //仅从二级缓存读数据,而不向二级缓存写数据
            session.setCacheMode(CacheMode.GET);
            
            Student student = (Student)session.load(Student.class1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        
        //新开的session,所以一级缓存中是没有数据的
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            //此时二级缓存中是没有数据的,要读出数据,得先发select查
            Student student = (Student)session.load(Student.class1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
                
    }    
    
    
    //Test3:先设置load的模式为:CacheMode.GET,再load默认,再load默认
    
//测试结果:select ... select  ... ...
    public void testCache4_C_CacheModeGET_defaultLoad__defaultLoad() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            //仅从二级缓存读数据,而不向二级缓存写数据
            session.setCacheMode(CacheMode.GET);
            
            Student student = (Student)session.load(Student.class1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        
        
        //新开的session,所以一级缓存中是没有数据的
        
//下面的第二个session中,二级缓存中被写入数据
        try {
            
            session = HibernateUtils.getSession();
            session.beginTransaction();
            //此时二级缓存中是没有数据的,要读出数据,得先发select查
            Student student = (Student)session.load(Student.class1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        //新开每三个session
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            //不发sql,因为第二个session中,二级缓存中被写入数据,所以在第三个session中直接使用
            Student student = (Student)session.load(Student.class1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        
    }    
    
    //Test4:先设置load的模式为:load=CacheMode.GET,再load默认,再load=CacheMode.PUT
    
//测试结果:select ... select ... select ... 
    public void testCache4_D_CacheModeGET_defaultLoad_CacheModePUT() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            //仅从二级缓存读数据,而不向二级缓存写数据
            session.setCacheMode(CacheMode.GET);
            Student student = (Student)session.load(Student.class1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            //发出sql语句,因为session设置了CacheMode为GET,所以二级缓存中没有数据
            
//此时二级缓存中是没有数据的,要读出数据,得先发select查
            Student student = (Student)session.load(Student.class1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            //只向二级缓存写数据,而不从二级缓存读数据
            session.setCacheMode(CacheMode.PUT);
            
            //会发出查询sql,因为session将CacheMode设置成了PUT
            Student student = (Student)session.load(Student.class1);
            System.out.println("student.name=" + student.getName());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
        
    }    

/*    20:38:10,265  WARN CacheFactory:43 - read-only cache configured for mutable class: com.bjsxt.hibernate.Student
    20:38:10,265  WARN EhCacheProvider:86 - Could not find configuration [com.bjsxt.hibernate.Student]; using defaults.
    Hibernate: select student0_.id as id1_0_, student0_.name as name1_0_, student0_.classesid as classesid1_0_ from t_student student0_ where student0_.id=?
    student.name=班级0的学生0
    Hibernate: select student0_.id as id1_0_, student0_.name as name1_0_, student0_.classesid as classesid1_0_ from t_student student0_ where student0_.id=?
    student.name=班级0的学生0
    Hibernate: select student0_.id as id1_0_, student0_.name as name1_0_, student0_.classesid as classesid1_0_ from t_student student0_ where student0_.id=?
    student.name=班级0的学生0
*/
}
原文地址:https://www.cnblogs.com/alamps/p/2633062.html