标签:hibernate
什么是缓存?
在内存里开辟一块空间把本来应该存在硬盘里面的数据,存在这个空间里面,将来,需要这块数据的时候直接在内存中获取。这个就可以简单理解为缓存。
Hibernate 是一个持久层框架,经常访问物理数据库,为了减低应用程序对物理数据源的访问频次,从而提高应用程序的运行性能。
缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件,将同步缓存和物理数据源的数据。
那么,接下来,让我们来看看Hibernate的缓存原理是什么。
首先,Hibernate的缓冲分两个级别:一级缓存 和 二级缓存。Hibernate一级缓存又称为 Session级别的缓存 ; 二级缓存又称为“SessionFactory的缓存”。由session ,和SessionFactory 中就可以看出,缓冲的作用范围不同。看两者的使用。
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来取值。
二级缓存又称为“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"/>
其实二级缓冲并不是由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
原文地址:http://blog.csdn.net/wangyongxia921/article/details/48141901