您的位置:首页 > 其它

hibernate缓存

2013-11-06 20:23 323 查看
Hibernate是一个持久层框架,经常访问物理数据库,为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能。缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻,会同步缓存和物理数据源中的数据。

一、Hibernate的一级缓存和二级缓存

1、一级缓存的管理

Hibernate一级缓存又称为“Session的缓存”,它是内置的,不能被卸载(不能被卸载的意思就是这种缓存不具有可选性,必须有的功能,不可以取消session缓存)。由于Session的生命周期通常对应一个数据库事务或者一个应用事务,因此它的缓存是事务范围的缓存。第一级缓存是必需的,不允许而且事实上也无法卸除。在第一级缓存中,持久化类的每个实例都具有唯一的OID。

当应用程序调用Session的save()、update()、savaeOrUpdate()、get()或load(),以及调用查询接口的list()、iterate()或filter()方法时,如果Session缓存中还不存在相应的对象,Hibernate就会把该对象加入到第一级缓存中。当清理缓存时,Hibernate会根据缓存中对象的状态变化来同步更新数据库。注意:find()方法每次都会查询数据库。

一级缓存只缓存实体对象,不会缓存普通属性。session间不能共享一级缓存数据,一级缓存会随着session消亡而消亡。session级的缓存对性能的提高没有太大的意义,因为生命周期太短了。

session为应用程序提供了两个管理缓存的方法:evict(Object obj):从缓存中清除参数指定的持久化对象。clear():清空缓存中所有持久化对象。

2、二级缓存的管理

Hibernate二级缓存又称为“SessionFactory的缓存”,由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此Hibernate二级缓存是进程范围或者集群范围的缓存,有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供事务隔离级别。第二级缓存是可选的,是一个可配置的插件,在默认情况下,SessionFactory不会启用这个插件。

二级缓存是进程级的缓存,session间可以共享一级缓存数据,不会存放普通属性,这和一级缓存是一样的,只存放实体对象。

二级缓存必须让sessionfactory管理,让sessionfactory来清除二级缓存。sessionFactory.evict(Student.class);//清除二级缓存中所有student对象sessionFactory.evict(Student.class,1);//清除二级缓存中id为1的student对象。

我们在实际应用中,主要用到Hibernate二级缓存。

首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。

4) 删除、更新、增加数据的时候,同时更新缓存。

Hibernate的二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无作用。为此,Hibernate提供了针对条件查询的Query Cache。

适合存放到第二级缓存中的数据

1 很少被修改的数据

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

3 不会被并发访问的数据

4 参考数据,指的是供应用参考的常量数据,它的实例数目有限,它的实例会被许多其他类的实例引用,实例极少或者从来不会被修改。

不适合存放到第二级缓存的数据

1 经常被修改的数据

2 财务数据,绝对不允许出现并发

3 与其他应用共享的数据。

二、Hibernate中二级缓存的配置和使用

Hibernate的二级缓存利用了第三方缓存插件,多数情况下使用的第三方缓存插件是ehcache。

启用Hibernate二级缓存通常通过spring来管理,具体步骤如下:

1、添加ehcache.xml放到项目源文件目录(如src/main/resourse),该文件中配置了缓存策略,如下

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">

<diskStore path="java.io.tmpdir/EhCacheSpringAnnotationsExampleApp" />
<defaultCache eternal="false" maxElementsInMemory="1000"
overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU" />

<cache name="DEFAULT_CACHE" eternal="false" maxElementsInMemory="100"
overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
timeToLiveSeconds="300" memoryStoreEvictionPolicy="LRU" />

<!-- 自动义的缓存,名字为Test,其他属性根据名字就可以知道它的意思 -->
<cache name="TEST" eternal="false" maxElementsInMemory="100"
overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
timeToLiveSeconds="300" memoryStoreEvictionPolicy="LRU" />

</ehcache>


2、在spring配置文档中启用echcache,配置如下,加入以下bean配置到applicationContext.xml文档中即可。

<!-- 缓存,用注解方式添加缓存 -->
<ehcache:annotation-driven cache-manager="ehCacheManager" />
<bean id="ehCacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />


3、在代码中加入缓存注解就可以实现ehcache缓存

分为类注解和方法注解

以下是方法注解,只针对该方法进行缓存(类缓存针对类中的所有的方法进行缓存,只需要将注解表在类名上即可)

@Cacheable(cacheName = "TEST")
public void test() {
String hql = "from CourseDO where CName='软件工程与计算'";
CourseDO courseDO = (CourseDO) getHibernateTemplate().find(hql).get(0);
}


执行几次该函数,可以看到只执行了一次hql语句来查询数据库。结果如下:只有一条hql语句输出

Hibernate: select coursedo0_.c_id as c1_0_, coursedo0_.c_name as c2_0_, coursedo0_.c_type as c3_0_, coursedo0_.t_id as t4_0_, coursedo0_.time as time0_ from xkxtbeta.course coursedo0_ where coursedo0_.c_name='软件工程与计算'
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: