Hibernate 中二级缓存及简单实例说明

1. 缓存

     缓存(Cache): 介于应用程序永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写硬盘(永久性数据存储源)的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的拷贝,缓存的物理介质通常是内存。

2. 二级缓存

 Hibernate 提供缓存机制:一级缓存、二级缓存

       一级缓存:线程级别的,session级别缓存,在一次请求中共享数据。

       二级缓存:进程级别的,sessionFactory级别缓存,整个应用程序共享一个会话工厂,共享一个二级缓存。SessionFactory的缓存两部分:内置缓存:使用一个Map,用于存放配置信息,预定义HQL语句等,提供给Hibernate框架自己使用,对外只读的,不能操作。外置缓存:使用另一个Map,用于存放用户自定义数据。默认不开启。外置缓存hibernate只提供规范(接口),需要第三方实现类。外置缓存又成为二级缓存。

3.二级缓存构成

       二级缓存有四部分构成,分别是其一是类级别缓存,其二是集合级别缓存,其三是查询缓存,其四是时间戳。

4.并发策略

         并发策略有四种,分别是transactional ,read-write,nonstrict-read-write ,read-only;  

一般选用read-write,read-only

5.应用场景

        适合使用二级缓存的:

                1>很少被修改;

                2>不是很重要的数据,允许出现偶尔并发问题。

        不适合使用二级缓存的:

                1>经常被修改;

                2>财务数据,绝对不能出现并发问题;

                3>与其他应用程序共享的数据

6. 应用实例

    1>类级别缓存

@Test
    public void fun1(){
        Session session = HibernateUtils.OpenSession();
        session.beginTransaction();
        //------------------------------
        Customer c1 = (Customer)session.get(Customer.class,1);
        session.clear();//关闭一级缓存
        Customer c2 = (Customer)session.get(Customer.class,1);
        System.out.println(c1 == c2);
        //------------------------------
        session.getTransaction().commit();
        session.close();
    }

结果:false

分析:console端打印一条SQL 语句 = >二级cache存在, false => 二级缓存不是对象

类级别缓存存储的数据对象的散列信息,使用时在一级缓存中组装成对象。

 2>集合级别缓存

  @Test
    public void fun1(){
        Session session = HibernateUtils.OpenSession();
        session.beginTransaction();
        //------------------------------
        Customer c1 = (Customer)session.get(Customer.class,1);
        for(Order o : c1.getOrders()){
            System.out.println(o.getName());
        }
        session.clear();
        Customer c2 = (Customer)session.get(Customer.class,1);
        Iterator<Order> it = c2.getOrders().iterator();
        while (it.hasNext()){
            Order o = it.next();
            System.out.println(o.getName());
        }
        //------------------------------
        session.getTransaction().commit();
        session.close();

    }

结果:运行到c2, 通过查询order 的id 查询order

分析:集合级别缓存存储的是customer 的id ,以及customer下 order的id 信息。

3>查询缓存

 //查询缓存
    // 注意:对HQL查询
    @Test
    public void fun1(){
        Session session = HibernateUtils.OpenSession();
        session.beginTransaction();
        //------------------------------
        Query query = session.createQuery("from Customer");
        //使用二级查询缓存
        query.setCacheable(true);
        //查询时,优先从二级缓存中查找,若没有就执行语句,将结果放入二级缓存中
        List<Customer> list = query.list();

        session.clear();


        Query query2 = session.createQuery("select c  from Customer c");
        //使用二级查询缓存
        query2.setCacheable(true);
        //查询时,优先从二级缓存中查找,若没有就执行语句,将结果放入二级缓存中
        List<Customer> list2 = query2.list();
        //------------------------------
        session.getTransaction().commit();
        session.close();

    }

结果:query2 没有打印sql语句

分析:查询缓存中存取的不是HQL语句,而是HQL对应生成的sql语句

4> 时间戳缓存

    //timestamp
    // 注意:对HQL查询
    @Test
    public void fun1(){
        Session session = HibernateUtils.OpenSession();
        session.beginTransaction();
        //------------------------------
        Customer c1 = (Customer) session.get(Customer.class,1);
        System.out.println(c1.getName());
        session.createQuery("update Customer set name=:name where id=:id")
                .setString("name","jack").setInteger("id",1).executeUpdate();
        session.clear();
        Customer c2 = (Customer) session.get(Customer.class,1);
        System.out.println(c2.getName());
        //------------------------------
        session.getTransaction().commit();
        session.close();

    }

结果:jack

分析:c1 数据存到缓存中,此时time1,但是后面执行了跟新数据库的操作,此时time2,再次查询时,会对比两个时间,time2 较新,所以c2会重新查看数据库,并且更新缓存。时间戳是保证存储在缓存区的数据是有效的。

猜你喜欢

转载自blog.csdn.net/py_tamir/article/details/80278630