hibernate学习笔记:hibernate中的Cache管理

Hibernate 中实现了良好的Cache 机制,咱们能够借助Hibernate 内部的Cache迅速提升系统数据读取性能。

须要注意的是:Hibernate作为一个应用级的数据访问层封装,只能在其做用范围内保持Cache中数据的的有效性,也就是说,在咱们的系统与第三方系统共享数据库的状况下,Hibernate的Cache机制可能失效。一个很简单的例子,若是你用access修改了库中的值,那么这就不会更新JVM中的缓冲池,这就致使了赃数据的产生。

Hibernate 在本地JVM 中维护了一个缓冲池,并将从数据库得到的数据保存到池中以供下次重复使用(若是在Hibernate中数据发生了变更,Hibernate一样也会更新池中的数据版本)。此时,若是有第三方系统对数据库进行了更改,那么,Hibernate并不知道数据库中的数据已经发生了变化,也就是说,池中的数据仍是修改以前的版本,下次读取时,Hibernate会将此数据返回给上层代码,从而致使潜在的问题。外部系统的定义,并不是限于本系统以外的第三方系统,即便在本系统中,若是出现了绕过Hibernate数据存储机制的其余数据存取手段,那么Cache的有效性也必须细加考量。如,在同一套系统中,基于Hibernate和基于JDBC的两种数据访问方式并存,那么经过JDBC更新数据库的时候,Hibernate一样没法获知数据更新的状况,从而致使脏数据的出现。

基于Java 的Cache 实现,最简单的莫过于HashTable,hibernate 提供了基于Hashtable 的Cache 实现机制,不过,因为其性能和功能上的局限,仅供开发调试中使用。同时,Hibernate 还提供了面向第三方Cache 实现的接口,如JCS、EHCache、OSCache、JBoss Cache、SwarmCache等。

Hibernate中的Cache大体分为两层,第一层Cache在Session实现,属于事务级数据缓冲,一旦事务结束,这个Cache 也就失效。此层Cache 为内置实现,无需咱们进行干涉。第二层Cache,是Hibernate 中对其实例范围内的数据进行缓存的管理容器。

咱们主要学习第二层Cache。

Hibernate早期版本中采用了JCS(Java Caching System -Apache Turbine项目中的一个子项目)做为默认的第二层Cache实现。因为JCS的发展停顿,以及其内在的一些问题(在某些状况下,可能致使内存泄漏以及死锁),新版本的Hibernate已经将JCS去除,并用EHCache做为其默认的第二级Cache实现。相对JCS,EHCache更加稳定,并具有更好的缓存调度性能,缺陷是目前还没法作到分布式缓存,若是咱们的系统须要在多台设备上部署,并共享同一个数据库,必须使用支持分布式缓存的Cache实现(如JCS、JBossCache)以免出现不一样系统实例之间缓存不一致而致使脏数据的状况。Hibernate对Cache进行了良好封装,透明化的Cache机制使得咱们在上层结构的实现中无需面对繁琐的Cache维护细节。

目前Hibernate支持的Cache实现有:

HashTable:net.sf.hibernate.cache.HashtableCacheProvider 支持查询缓冲。

EHCache:net.sf.ehcache.hibernate.Provider 支持查询缓冲。

OSCache:net.sf.hibernate.cache.OSCacheProvider 支持查询缓冲。

SwarmCache:net.sf.hibernate.cache.SwarmCacheProvider 支持集群。

JBossCache:net.sf.hibernate.cache.TreeCacheProvider 支持集群。

其中SwarmCache 提供的是invalidation 方式的分布式缓存,即当集群中的某个节点更新了缓存中的数据,即通知集群中的其余节点将此数据废除,以后各个节点须要用到这个数据的时候,会从新从数据库中读入并填充到缓存中。而JBossCache提供的是Reapplication式的缓冲,即若是集群中某个节点的数据发生改变,此节点会将发生改变的数据的最新版本复制到集群中的每一个节点中以保持全部节点状态一致。

使用第二层Cache,须要在hibernate的配置文件进行配置(省略)主要介绍一下cache策略

cache策略可选值有如下几种:

1. read-only 只读。
2. read-write 可读可写。
3. nonstrict-read-write 若是程序对并发数据修改要求不是很是严格,只是偶尔须要更新数据,能够采用本选项,以减小无谓的检查,得到较好的性能。
4. transactional 事务性cache。在事务性Cache 中,Cache 的相关操做也被添加到事务之中,若是因为某种缘由致使事务失败,咱们能够连同缓冲池中的数据一同回滚到事务开始以前的状态。目前Hibernate 内置的Cache 中,只有JBossCache 支持事务性的Cache实现。

其余参数简介:

maxElementsInMemory="10000" //Cache中最大容许保存的数据数量
eternal="false" //Cache中数据是否为常量
timeToIdleSeconds="120" //缓存数据钝化时间
timeToLiveSeconds="120" //缓存数据的生存时间
overflowToDisk="true" //内存不足时,是否启用磁盘缓存


须要注意的是Hibernate 的数据库查询机制。咱们从查询结果中取出数据的时候,用的最多的是两个方法:Query.list();Query.iterate();

对于list方法而言,实际上Hibernate是经过一条Select SQL获取全部的记录。并将其读出,填入到POJO中返回。

而iterate 方法,则是首先经过一条Select SQL 获取全部符合查询条件的记录的id,再对这个id 集合进行循环操做,经过单独的Select SQL 取出每一个id 所对应的记录,以后填入POJO中返回。

也就是说,对于list 操做,须要一条SQL 完成。而对于iterate 操做,须要n+1条SQL。

看上去iterate方法彷佛有些多余,但在不一样的状况下确依然有其独特的功效,如对海量数据的查询,若是用list方法将结果集一次取出,内存的开销可能没法承受。另外一方面,对于咱们如今的Cache机制而言,list方法将不会从Cache中读取数据,它老是一次性从数据库中直接读出全部符合条件的记录。而iterate 方法由于每次根据id获取数据,这样的实现机制也就为从Cache读取数据提供了可能,hibernate首先会根据这个id 在本地Cache 内寻找对应的数据,若是没找到,再去数据库中检索。数据库

 

资料:Hibernate 开发指南缓存

相关文章
相关标签/搜索