码迷,mamicode.com
首页 > Web开发 > 详细

Hibernate缓冲策略 一

时间:2015-08-31 23:45:03      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:hibernate

一、hibernate为什么提供缓存?

什么是缓存?
在内存里开辟一块空间把本来应该存在硬盘里面的数据,存在这个空间里面,将来,需要这块数据的时候直接在内存中获取。这个就可以简单理解为缓存。
Hibernate 是一个持久层框架,经常访问物理数据库,为了减低应用程序对物理数据源的访问频次,从而提高应用程序的运行性能。
缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件,将同步缓存和物理数据源的数据。
那么,接下来,让我们来看看Hibernate的缓存原理是什么。

二、Hibernate 的缓存

首先,Hibernate的缓冲分两个级别:一级缓存 和 二级缓存。Hibernate一级缓存又称为 Session级别的缓存 ; 二级缓存又称为“SessionFactory的缓存”。由session ,和SessionFactory 中就可以看出,缓冲的作用范围不同。看两者的使用。

1、一级缓冲

Hibernate一级缓存又称为 Session级别的缓存 。Session的缓存是事务范围的缓存,所以一级缓冲的生命周期和session的生命周期是同步的。Session对象的生命周期通常对应一个数据库事务或者一个应用事务。在一级缓存中,持久化类的每个实例都具有唯一的OID。

在同一个session中,我们两次使用load来加载同一个对象,来看一级缓存:

@Test
 publicvoid cache1Test(){
       Session s=sessionFactory.openSession();
       s.beginTransaction();
       Person person=(Person)s.load(Person.class, 1);
       System.out.println(person.getName());
       //因为Session存在缓冲,所以第二次查询直接在session中取
       Person person2=(Person)s.load(Person.class, 1);
       System.out.println(person2.getName());
       s.getTransaction().commit();
    }

结果是只发出一条SQL语句,是第一个查询的sql语句,第二次查询直接使用的session缓冲中的数据对象。
这就是一级缓冲,只能用在同一个session中,不能跨session来取值,那要是需要跨session取值,怎么办呢?
对了,就是sessionFactory级别的缓冲,就像是sessionFactory管理所有的session一样,这里的二级缓冲就跳出来session的小圈子,可以供所有的session来取值。

2、二级缓存。

二级缓存又称为“SessionFactory的缓存”。是SessionFactory级别的缓冲,由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此Hibernate二级缓存是进程范围的缓存,有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。

二级缓存是可选的,是一个可配置的第三方插件,默认下SessionFactory不会启用这个插件,如果我们需要使用二级缓冲,就事先需要开启。

第一、开启缓存

我们需要在我们的hibernate.cfg.xml中开启我们的二级缓冲,如下:

<!-- 开启缓冲 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!--指定是哪个二级缓冲-->
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<!-- 使用查询二级缓冲 -->
<propertyname="hibernate.cache.use_query_cache">true</property>

第二:指明那个实体类需要使用缓冲

我们需要指明那个实体类需要使用缓冲,这里有两种配置,一种是xml配置,一种是Annotation的配置,分别如下:

Annotation的配置如下:

@Entity
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
@Table(name="p_person")
public class Persion{

}

Xml的配置也有两种,一种是在各自的hbm文件配置,一种是在cfg中配置,
hbm文件的配置如下:

<class name="Person" table="t_person">
        <cache usage="read-write"/>
        <id name="id">
        ……
</class>

cfg文件的配置如下:

<!-- 指定Student使用二级缓存     -->
<class-cache class="com.hibernate.Persion" usage="read-only"/>

第三:需要提供第三方的cache。

其实二级缓冲并不是由Hibernate来提供,是由第三方提供的缓冲插件,通常有以下几种第三方缓冲插件:

  • EhCache:可作为进程范围的缓存,存放数据的物理介质可以是内存或硬盘,对Hibernate的查询缓存提供了支持。
  • OSCache:可作为进程范围的缓存,存放数据的物理介质可以是内存或硬盘,提供了丰富的缓存数据过期策略,对Hibernate的查询缓存提供了支持。
  • SwarmCache:可作为集群范围内的缓存,但不支持Hibernate的查询缓存。
  • JBossCache:可作为集群范围内的缓存,支持事务型并发访问策略,对Hibernate的查询缓存提供了支持。

默认hibernate使用的是ehcache。默认的配置如下:

<defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        />

到这里配置结束,我们来进行测试。

 @Test
    publicvoid findTesterjihuanchong(){
        Sessions=sessionFactory.openSession();
        s.beginTransaction();
        Personperson=(Person)s.load(Person.class, 1);
        System.out.println(person.getName());
        s.getTransaction().commit();
        s.close();   
        // 另起一个session  
        Sessions2=sessionFactory.openSession();
        s2.beginTransaction();
        // 不会发SQL语句,读取的是二级缓存中的数据
        Personperson2=(Person)s2.load(Person.class, 1);
        System.out.println(person2.getName());
        s2.getTransaction().commit();
        s2.close();
    }

结果是:只有第一个session中发送了一条SQL语句,第二个session中没有发送。

以上是Hibernate的 一级缓存和二级缓存的介绍,其实 Hiberante还有第三种缓存:查询缓存。什么是查询缓存?查询缓冲和一级,二级缓存的区别是什么,将在下篇博客中说明。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Hibernate缓冲策略 一

标签:hibernate

原文地址:http://blog.csdn.net/wangyongxia921/article/details/48141901

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!