zoukankan      html  css  js  c++  java
  • 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
    */
    }
  • 相关阅读:
    RTThread | 启动下一代RTOS演化
    开发者应该开始学习C++吗?
    用googleperftool分析程序的内存/CPU使用
    看书看累了,可以换看技术视频也是一种学习的方式
    分享:nginx virtuanenv django1.4 应用简单部署
    分享:不同编程语言之间转换的项目矩阵
    【EDUPEPN8508GS黄金版】EDUP EPN8508GS黄金版 迷你USB无线网卡【行情 报价 价格 评测】
    分享:20 本优秀的 Python 电子书
    说说设计模式~工厂方法模式(Factory Method)
    说说设计模式~简单工厂模式(Factory)
  • 原文地址:https://www.cnblogs.com/alamps/p/2633062.html
Copyright © 2011-2022 走看看