• 29.Hibernate-二级缓存和session管理.md



    目录

    1.概念

    Hibernate提供的缓存
    有一级缓存、二级缓存。 目的是为了减少对数据库的访问次数,提升程序执行效率!

    1.1一级缓存:

         基于Session的缓存,缓存内容只在当前session有效,session关闭,缓存内容失效!
         特点: 
                   作用范围较小! 缓存的事件短。
                   缓存效果不明显。
    

    1.2二级缓存:

         Hibernate提供了基于应用程序级别的缓存, 可以跨多个session,即不同的session都可以访问缓存数据。 这个换存也叫二级缓存。
         Hibernate提供的二级缓存有默认的实现,且是一种可插配的缓存框架!如果用户想用二级缓存,只需要在hibernate.cfg.xml中配置即可;不想用,直接移除,不影响代码。
         如果用户觉得hibernate提供的框架框架不好用,自己可以换其他的缓存框架或自己实现缓存框架都可以。
    

    2.使用方法

    查看hibernate.properties配置文件,二级缓存如何配置?


    ---Second-level Cache---


    -hibernate.cache.use_second_level_cache false【二级缓存默认不开启,需要手动开启】
    -hibernate.cache.use_query_cache true 【开启查询缓存】

    --choose a cache implementation 【二级缓存框架的实现】

    -hibernate.cache.provider_class org.hibernate.cache.EhCacheProvider
    -hibernate.cache.provider_class org.hibernate.cache.EmptyCacheProvider
    -hibernate.cache.provider_class org.hibernate.cache.HashtableCacheProvider 默认实现
    -hibernate.cache.provider_class org.hibernate.cache.TreeCacheProvider
    -hibernate.cache.provider_class org.hibernate.cache.OSCacheProvider
    -hibernate.cache.provider_class org.hibernate.cache.SwarmCacheProvider

    二级缓存,使用步骤

    1. 开启二级缓存
      2)指定缓存框架
      3)指定那些类加入二级缓存
      4)测试
      测试二级缓存!

    3.策略

    3.1缓存策略

    <class-cache usage="read-only"/>     放入二级缓存的对象,只读; 
             <class-cache usage="nonstrict-read-write"/>  非严格的读写
             <class-cache usage="read-write"/>    读写; 放入二级缓存的对象可以读、写;
             <class-cache usage="transactional"/>   (基于事务的策略)
    

    3.2集合缓存

    <!-- 集合缓存[集合缓存的元素对象,也加加入二级缓存] -->
          <collection-cache 
    usage="read-write" collection="cn.itcast.b_second_cache.Dept.emps"/>
    

    3.3查询缓存

    
    
    ``
    
    
     # 4.实例
    ```xml
    <!--****************** 【二级缓存配置】****************** -->
            <!-- a.  开启二级缓存 -->
            <property name="hibernate.cache.use_second_level_cache">true</property>
            <!-- b. 指定使用哪一个缓存框架(默认提供的) -->
            <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
            <!-- 开启查询缓存 -->
            <property name="hibernate.cache.use_query_cache">true</property>
            <!-- c. 指定哪一些类,需要加入二级缓存 -->
            <class-cache usage="read-write"class="cn.itcast.b_second_cache.Dept"/>
            <class-cache usage="read-only"class="cn.itcast.b_second_cache.Employee"/>
            <!-- 集合缓存[集合缓存的元素对象,也加加入二级缓存] -->
            <collection-cache usage="read-write"collection="cn.itcast.b_second_cache.Dept.emps"/>
    
    public class App {
        
        private static SessionFactory sf;
        static {
            sf = new Configuration()
                .configure()
                .addClass(Dept.class)   
                .addClass(Employee.class)   // 测试时候使用
                .buildSessionFactory();
        }
        // 1. 测试二级缓存的使用
        // 没有/有用 二级缓存
        @Test
        public void testCache() {
            Session session1 = sf.openSession();
            session1.beginTransaction();
            // a. 查询一次
            Dept dept = (Dept) session1.get(Dept.class, 10);
            dept.getEmps().size();// 集合
            session1.getTransaction().commit();
            session1.close();
            
            System.out.println("------");
            
            // 第二个session
            Session session2 = sf.openSession();
            session2.beginTransaction();
            // a. 查询一次
            dept = (Dept) session2.get(Dept.class, 10);// 二级缓存配置好; 这里不查询数据库
            dept.getEmps().size();
            
            session2.getTransaction().commit();
            session2.close();
        }
        
        
        @Test
        public void listCache() {
            Session session1 = sf.openSession();
            session1.beginTransaction();
            // HQL查询  【setCacheable  指定从二级缓存找,或者是放入二级缓存】
            Query q = session1.createQuery("from Dept").setCacheable(true);
            System.out.println(q.list());
            session1.getTransaction().commit();
            session1.close();
            
            
            Session session2 = sf.openSession();
            session2.beginTransaction();
            q = session2.createQuery("from Dept").setCacheable(true);
            System.out.println(q.list());// 不查询数据库: 需要开启查询缓存
            session2.getTransaction().commit();
            session2.close();
        }
    }
    

    5. Seesion管理

        public void testSession() throws Exception {
            //openSession:  创建Session, 每次都会创建一个新的session
            Session session1 = sf.openSession();
            Session session2 = sf.openSession();
            System.out.println(session1 == session2);
            session1.close();
            session2.close();
            
            //getCurrentSession 创建或者获取session
            // 线程的方式创建session
            // 一定要配置:<property name="hibernate.current_session_context_class">thread</property>
            Session session3 = sf.getCurrentSession();// 创建session,绑定到线程
            Session session4 = sf.getCurrentSession();// 从当前访问线程获取session
            System.out.println(session3 == session4);
            
            // 关闭 【以线程方式创建的session,可以不用关闭; 线程结束session自动关闭】
            //session3.close();
            //session4.close(); 报错,因为同一个session已经关闭了!
    
  • 相关阅读:
    vim使用技巧
    排序
    2020-3-27 学习面向对象的笔记
    小圆圈第三章答案
    内置函数部分用法
    Pycharm快捷键
    小猿圈第二章答案
    Typora学习笔记
    AI的真实感
    Unity 横版2D移动跳跃问题——关于一段跳与二段跳
  • 原文地址:https://www.cnblogs.com/bugstar/p/8512922.html
Copyright © 2020-2023  润新知