bugstar

导航

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已经关闭了!

posted on 2018-03-06 10:31  bugstar  阅读(161)  评论(0编辑  收藏  举报