zoukankan      html  css  js  c++  java
  • Hibernate第十二篇【二级缓存介绍、缓存策略、查询缓存、集合缓存】

    Hibernate二级缓存介绍

    前面我们已经讲解过了一级缓存,一级缓存也就是Session缓存,只在Session的范围内有效…作用时间就在Session的作用域中,范围比较小

    Hibernate为我们提供了二级缓存功能:二级缓存是基于应用程序的缓存,所有的Session都可以使用

    • Hibernate提供的二级缓存有默认的实现,且是一种可插配的缓存框架!如果用户想用二级缓存,只需要在hibernate.cfg.xml中配置即可; 不想用,直接移除,不影响代码。
    • 如果用户觉得hibernate提供的框架框架不好用,自己可以换其他的缓存框架或自己实现缓存框架都可以

    这里写图片描述

    Hibernate二级缓存:存储的是常用的类


    配置二级缓存

    既然二级缓存是Hibernate自带的,那么我们可以在hibernate.properties文件中找到对应的信息..

    这里写图片描述

    • #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)指定哪些类加入二级缓存

    开启二级缓存

    在hibernate.cfg.xml文件中开启二级缓存

    
            <!-- a.  开启二级缓存 -->
            <property name="hibernate.cache.use_second_level_cache">true</property>

    指定缓存框架

    指定Hibernate自带的二级缓存框架就好了

    
            <!-- b. 指定使用哪一个缓存框架(默认提供的) -->
            <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>

    指定哪些类加入二级缓存

    
            <!-- c. 指定哪一些类,需要加入二级缓存 -->
            <class-cache usage="read-write" class="zhongfucheng.aa.Monkey"/>
            <class-cache usage="read-only" class="zhongfucheng.aa.Cat"/>

    测试

    我们知道一级缓存是Session的缓存,那么我们在测试二级缓存的时候使用两个Session来测试就好了。如果第二个Session拿到的是缓存数据,那么就证明二级缓存是有用的。

    
    package zhongfucheng.aa;
    
    import org.hibernate.SessionFactory;
    import org.hibernate.Transaction;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.classic.Session;
    
    public class App5 {
        public static void main(String[] args) {
    
    
            //获取加载配置管理类
            Configuration configuration = new Configuration();
            //加载类对应的映射文件!
            configuration.configure().addClass(Animal.class);
            //创建Session工厂对象
            SessionFactory factory = configuration.buildSessionFactory();
            //得到Session对象
            Session session1 = factory.openSession();
            //使用Hibernate操作数据库,都要开启事务,得到事务对象
            Transaction transaction = session1.getTransaction();
            //开启事务
            transaction.begin();
            Monkey monkey = (Monkey) session1.get(Monkey.class,"40283f815be67f42015be67f43240001" );
            System.out.println(monkey.getName());
            System.out.println("-----------------------");
    
    
    
            Session session2 = factory.openSession();
            Transaction transaction2 = session2.getTransaction();
            transaction2.begin();
            Monkey monkey2 = (Monkey) session1.get(Monkey.class, "40283f815be67f42015be67f43240001");
            System.out.println(monkey2.getName());
    
    
            //提交事务
            transaction.commit();
            transaction2.commit();
    
            //关闭Session
            session1.close();
            session2.close();
    
    
        }
    }
    

    得到的是缓存数据!

    这里写图片描述


    缓存策略

    我们在把Animal类放进二级缓存的时候,用法为只读

    这里写图片描述

    也就是说,只能读取,不能写入,我们来看看写入会怎么样:

    
      monkey2.setName("小猴子");

    抛出了异常….

    这里写图片描述


    usage的属性有4种:

    • 放入二级缓存的对象,只读;
    • 非严格的读写
    • 读写; 放入二级缓存的对象可以读、写;
    • (基于事务的策略)

    集合缓存

    如果我们在数据库查询的数据是集合…Hibernate默认是没有为集合数据设置二级缓存的…因此还是需要去读写数据库的信息

    接下来,我们就看看把集合设置为二级缓存是什么做的:

    • 在hibernate.cgf.xml中配置对象中的集合为二级缓存
            <!-- 集合缓存[集合缓存的元素对象,也加加入二级缓存] -->
            <collection-cache usage="read-write" collection="cn.itcast.b_second_cache.Dept.emps"/>
    • 测试代码:
    
        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();
        }

    查询缓存

    list()和iterator()会把数据放在一级缓存,但一级缓存只在Session的作用域中有效…如果想要跨Session来使用,就要设置查询缓存

    我们在配置文件中还看到了查询缓存这么一条配置..

        #hibernate.cache.use_query_cache true      【开启查询缓存】

    也就是说,默认的查询数据是不放在二级缓存中的,如果我们想要把查询出来的数据放到二级缓存,就需要在配置文件中开启

            <!-- 开启查询缓存 -->
            <property name="hibernate.cache.use_query_cache">true</property>
    • 在使用程序查询的时候,也要调用setCacheable()方法,设置为查询缓存。
    
        @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();
        }

  • 相关阅读:
    java继承
    c#中委托和事件区别
    c#委托中的匿名方法和lambda表达式
    c#中内置委托
    iOS消息推送获取不到deviceToken解决方案
    python+appium+iOS自动化测试case如何写?
    Xcode查看iOS崩溃与崩溃日志分析
    iOS性能检测工具instrunments简单介绍
    python实现使用代码进行代理配置
    python+locust性能测试-最简单的登录点击次数
  • 原文地址:https://www.cnblogs.com/zhong-fucheng/p/7202957.html
Copyright © 2011-2022 走看看