Hibernate进阶(二)Hibernate缓存机制

前言

     本章讲解Hibernate的缓存机制

方法

1.一级缓存

我们之前学习过MyBatis,那么Hibernate的一级缓存也是类似的,那就是session级别的缓存!

Hibernate默认也是开启一级缓存的,所以我们无需进行配置。

范例:使用get方法进行查询操作

import cn.edu.ccut.bo.Emp;
import cn.edu.ccut.util.DBUtil;
import org.hibernate.Session;
import org.junit.Test;

public class HibernateTest {

    @Test
    public void testHibernateConfig() throws Exception{
        Session session = DBUtil.getSession();
        Emp emp1 = (Emp)session.get(Emp.class, 7369);
        Emp emp2 = (Emp)session.get(Emp.class, 7369);
        System.out.println(emp1);
        DBUtil.close();
    }
}

我们可以看到,上面我们使用了两次查询,正常需要打印两次SQL语句,但是由于一级缓存的原因,故打印一份SQL,如下所示:

特别的:我们发现,使用list方法的时候,没有采用一级缓存,发送了两次SQL!!

2.二级缓存 

所谓二级缓存,那么和MyBatis一样,是SessionFactory级别的缓存,也就是说不同用户查询相同内容可以使用此缓存!

那么,Hibernate的二级缓存如何开启呢?由于Hibernate没有内置的缓存组件提供支持,需要第三方的jar来提供这方面的支持!

首先我们来看下面的一个例子:

import cn.edu.ccut.bo.Emp;
import cn.edu.ccut.util.DBUtil;
import org.hibernate.Session;
import org.junit.Test;

import java.util.List;

public class HibernateTest {

    @Test
    public void testHibernateConfig() throws Exception{
        /*Session session = DBUtil.getSession();
        List emps1 = session.createQuery("from Emp").list();
        List emps2 = session.createQuery("from Emp").list();
        System.out.println(emps1);
        DBUtil.close();*/
        Session session1 = DBUtil.getSession();
        Emp emp1 = (Emp)session1.get(Emp.class, 7369);
        Session session2 = DBUtil.getSession();
        Emp emp2 = (Emp)session2.get(Emp.class, 7369);
        DBUtil.close();
    }
}

该例子在没有设置二级缓存的情况下,将输出两条SQL语句!

1)配置二级缓存所需要的jar包

 

2) 在hibernate.cfg.xml中配置二级缓存

<!-- 开启二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- 二级缓存的提供类 在hibernate4.0版本以后我们都是配置这个属性来指定二级缓存的提供类-->
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<!-- 二级缓存配置文件的位置 -->
<property name="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</property>

其中ehache.xml为二级缓存的配置文件,配置文件大概配置如下所示:

<ehcache>

    <!-- Sets the path to the directory where cache .data files are created.

         If the path is a Java System Property it is replaced by
         its value in the running VM.

         The following properties are translated:
         user.home - User's home directory
         user.dir - User's current working directory
         java.io.tmpdir - Default temp file path -->
  
  <!--指定二级缓存存放在磁盘上的位置-->
    <diskStore path="user.dir"/>  

  <!--我们可以给每个实体类指定一个对应的缓存,如果没有匹配到该类,则使用这个默认的缓存配置-->
    <defaultCache
        maxElementsInMemory="10000"  //在内存中存放的最大对象数
        eternal="false"         //是否永久保存缓存,设置成false
        timeToIdleSeconds="120"    
        timeToLiveSeconds="120"    
        overflowToDisk="true"     //如果对象数量超过内存中最大的数,是否将其保存到磁盘中,设置成true
        />
  
  <!--
    1、timeToLiveSeconds的定义是:以创建时间为基准开始计算的超时时长;
    2、timeToIdleSeconds的定义是:在创建时间和最近访问时间中取出离现在最近的时间作为基准计算的超时时长;
    3、如果仅设置了timeToLiveSeconds,则该对象的超时时间=创建时间+timeToLiveSeconds,假设为A;
    4、如果没设置timeToLiveSeconds,则该对象的超时时间=max(创建时间,最近访问时间)+timeToIdleSeconds,假设为B;
    5、如果两者都设置了,则取出A、B最少的值,即min(A,B),表示只要有一个超时成立即算超时。

  -->

  <!--可以给每个实体类指定一个配置文件,通过name属性指定,要使用类的全名-->
    <cache name="com.xiaoluo.bean.Student"
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="600"
        overflowToDisk="true"
        />

    <cache name="sampleCache2"
        maxElementsInMemory="1000"
        eternal="true"
        timeToIdleSeconds="0"
        timeToLiveSeconds="0"
        overflowToDisk="false"
        /> -->


</ehcache>

3)在需要配置二级缓存的类上加入注解

 4)编写测试类测试代码

import cn.edu.ccut.bo.Emp;
import cn.edu.ccut.util.DBUtil;
import org.hibernate.Session;
import org.junit.Test;

import java.util.List;

public class HibernateTest {

    @Test
    public void testHibernateConfig() throws Exception{
        /*Session session = DBUtil.getSession();
        List emps1 = session.createQuery("from Emp").list();
        List emps2 = session.createQuery("from Emp").list();
        System.out.println(emps1);
        DBUtil.close();*/
        Session session1 = DBUtil.getSession();
        Emp emp1 = (Emp)session1.get(Emp.class, 7369);
        Session session2 = DBUtil.getSession();
        Emp emp2 = (Emp)session2.get(Emp.class, 7369);
        DBUtil.close();
    }
}

程序的运行结果为:

可见我们的二级缓存设置成功。

特别的:二级缓存未能解决诸如HQL语句的list方法查询出来的集合,将使用查询缓存进行处理

3.查询缓存 

需要注意的一点是,查询缓存务必在配置了二级缓存的基础上进行使用,否则没有丝毫意义!

1)hibernate.cfg.xml中配置使用查询缓存

<!-- 开启查询缓存 -->
<property name="hibernate.cache.use_query_cache">true</property>

2)在使用HQL等查询时使用如下方法使用查询缓存

import cn.edu.ccut.bo.Emp;
import cn.edu.ccut.util.DBUtil;
import org.hibernate.Session;
import org.junit.Test;

import java.util.List;

public class HibernateTest {

    @Test
    public void testHibernateConfig() throws Exception{
        Session session = DBUtil.getSession();
        List emps1 = session.createQuery("from Emp").setCacheable(true).list();
        List emps2 = session.createQuery("from Emp").setCacheable(true).list();
        System.out.println(emps1);
        DBUtil.close();
    }
}

3)运行结果如下所示

可见,我们实现了查询缓存。

特别的:查询缓存也是sessionFactory级别的缓存! 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值