《Hibernate 二级缓存总结.doc》由会员分享,可在线阅读,更多相关《Hibernate 二级缓存总结.doc(13页珍藏版)》请在金锄头文库上搜索。
1、缓存可以简单的看成一个 Map ,通过 key 在缓存里面找 value 。 一、缓存简介 Cache In Hibernate HIBERNATE 中的 CACHE 有两级 . 一级是在 Session 范围内的 CACHE . 即每个 Session 有自己的一个 CACHE, 当前操作的对象都会被保留在 CACHE 中 . 但是 Session 关闭后这个 CACHE 也就没有 . 可见这级 CACHE 的生命期是很短的 . (使用 id 进行关键字存储:缓存的 key 就是 ID , value 是 POJO ) ( 缓存的是实体对象 ) 另一级 CACHE 是在 SessionFac
2、tory 范围的 , 可以被来自同一个 SessionFactory 的 Session 共享 . 在 HIBERNATE 的文档中称其为 SECOND LEVEL CACHE. 显然后者的优势较明显 , 也比较复合当前的使用环境 . 它可以使用不同的缓存实现,如 EhCache 、 JBossCache 、 OsCache 等 (二级缓存是缓存实体对象的) 还有一个类型的 CACHE 就是 QueryCache . 它的作用就是缓存一个 Query 以及 Query 返回对象的 Identifier 以及对象的类型 . 有了 QueryCache 后就可以高效的使用 SECOND LEVEL
3、 CACHE. hibernate 查询缓存 (hibernate 默认是关闭的 ) 查询缓存是针对普通属性结果集的缓存 对实体对象的结果集只缓存 id 查询缓存的生命周期,当前关联的表发生修改,那么查询缓存生命周期结束 查询缓存的配置和使用: 1. 启用查询缓存:在 hibernate .cfg.xml 中加入: true 2. 在程序中必须手动启用查询缓存,如: query.setCacheable(true); QueryCache 用来缓存查询语句 , 及查询结果集中对象的 Identifier 与 Type. 当再次使用已缓存的 Query 时 , 就可以通过对象的 Identifi
4、er 与 Type 在 SECOND LEVEL CACHE 中查找实际的对象 . 对于查询缓存来说,缓存的 key 是根据 hql 生成的 sql ,再加上参数,分页等信息(可以通过日志输出看到,不过它的输出不是很可读,最好改一下它的代码)。 注:一级缓存也叫 session 级的缓存或事务缓存。 Hibernate 二级缓存也称为进程级的缓存或 SessionFactory 级的缓存。二级缓存是全局缓存,它可以被所有的 session 共享。二级缓存的生命周期和 SessionFactory 的生命周期一致, SessionFactory 可以管理二级缓存。 二、缓存的范围 缓存的范围分为
5、 3 类 : 1. 事务范围 事务范围的缓存只能被当前事务访问 , 每个事务都有各自的缓存 , 缓存内的数据通常采用相互关联的对象形式 . 缓存的生命周期依赖于事务的生命周期 , 只有当事务结束时 , 缓存的生命周期才会结束 . 事务范围的缓存使用内存作为存储介质 , 一级缓存就属于事务范围 . 2. 应用范围 应用程序的缓存可以被应用范围内的所有事务共享访问 . 缓存的生命周期依赖于应用的生命周期 , 只有当应用结束时 , 缓存的生命周期才会结束 . 应用范围的缓存可以使用内存或硬盘作为存储介质 , 二级缓存就属于应用范围 . 3. 集群范围 在集群环境中 , 缓存被一个机器或多个机器的进程
6、共享 , 缓存中的数据被复制到集群环境中的每个进程节点 , 进程间通过远程通信来保证缓存中的数据的一致 , 缓存中的数据通常采用对象的松散数据形式 . 三、缓存的方式 有四种,分别为: CacheConcurrencyStrategy.NONE CacheConcurrencyStrategy.READ_ONLY ,只读模式,在此模式下,如果对数据进行更新操作,会有异常; CacheConcurrencyStrategy.READ_WRITE ,读写模式在更新缓存的时候会把缓存里面的数据换成一个锁,其它事务如果去取相应的缓存数据,发现被锁了,直接就去数据库查询; CacheConcurrenc
7、yStrategy.NONSTRICT_READ_WRITE ,不严格的读写模式则不会的缓存数据加锁; CacheConcurrencyStrategy.TRANSACTIONAL ,事务模式指缓存支持事务,当事务回滚时,缓存也能回滚,只支持 JTA 环境。 缓存的注释写法如下,加在 Entity 的 java 类上: Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 缓存是提高硬件和应用程序性能的一个关键因素,在对象映射框架中更是如此。因此,合理使用缓存能够大幅度的提高Hibernate应用程序的性能。 Hibernat
8、e提供了两级缓存架构,第一级缓存是Session的缓存,第二级缓存是一个用户决定是否使用的缓存,能够借助与第三方的组件实现。Hibernate则提供了缓存管理接口,应用程序可以自由的对缓存进行管理。 缓存是对或计算代价较大的原始数据的复制存储。通过在缓存(连续的内存空间)存储数据,对缓存中的数据进行访问,可以缩短平均访问时间,提高数据的平均传输速度。 缓存首先出现在CPU中,由于CPU的速度很快,主存储器的存储速度无法与其相比,因而影响了计算机的执行效率。在CPU和主存储器之间加入了速度最快的SRAM作为CPU与相对低速的存储器之间交换数据的缓冲区,这样可以大幅度提高系统的执行效率,可且通过C
9、ACHE来事先读取CPU可能需要的数据。推广开来,凡是位于速度相差很大的两种硬件或应用之间的,用于协调两者数据传输差异的结构都可以称为缓存。 缓存将最近访问过的信息存储在特殊内存系统中以避免CPU在重新到主存储器中存取。在特定的硬件基础和应用架构之上,缓存往往是提升系统性能的关键因素之一。在使用数据库的应用系统中,缓存位于数据库和应用之间,在内存中保存底层数据库的数据副本(应用程序经常方位的数据),以便应用程序之间重内存中存取而不必频繁的方位数据库,因此提高了应用程序访问数据的效率。 缓存介于应用程序的数据访问层和数据库等数据源层之间,一般位于内存中,而数据库等数据源长来自硬盘或网络。相对于硬
10、盘和网络,应用程序访问内存的速度显然要快的很多。不过如果缓存中数据量太大也可以放置到硬盘上,需要时在掉入内存,这样虽然速度慢些,但还是比直接从网络获取要快! 对于Hibernate而言,它是一个实现了对象关系映射的组件。应用程序中的数据通过Hibernate中的持久化实例反映。这些持久化实例维护的数据是来自于底层数据库或即将同步更行到数据库的数据,为了获取这些数据,Hibernate必须频繁的访问数据库,产生大量的数据库连接操作和数据传输动作,效率较低。另外,Hibernate屏蔽了底层数据库的操作细节,让用户可以以操作对象的方式访问关系数据库中的数据,在对象关系映射转换的过程中,Hibern
11、ate势必付出了一些系统开销! 为了提升Hibernate的数据库访问效率并应对Hibernate封装底层数据库的内存开销,需要引入缓存策略。缓存作为数据库数据在内存中的临时容器,内涵了数据库数在内存中的临时副本。Hibernate读取所需数据时,首先在缓存中查找(先是一级缓存再次是二级缓存),若果缓存中存在需要的数据则称为命中(和CPU在一级缓存中取到需要的数据概念一样),然后就会直接返回数据,这样的话就避免了数据库调用的开销,不过如果缓存中没有所需要的数据还是会访问底层数据库。 Hibernate采用二级缓存体系,包括Session缓存(一级缓存)和SessionFactory缓存(二级缓
12、存)。 (1)Session缓存是内置的,默认的,不能被卸载。Session维护了其自身生命周期中的一些持久化实例和它们的集合。(就像是一个方法中的变量) (2)SessionFactory缓存即Hibernate二级缓存,按结构可以分为内置缓存和外置缓存两种。 针对缓存的生命周期的不同,我们可以将Hibernate的缓存分为三个层次: 1.事物级缓存 缓存只能被当前事物访问。这个事物可以是一个数据库事物(比如Session),也可以是某个应用程序大的事物。缓存的声明周期依赖于事物的生命周期,很显然,就像是一个方法中的变量(内部变量)方法执行完后,其内部变量就会小时除非我们在那个方法中将其存入
13、一个全局变量的集合类中。因此,对于Session而言,事物级缓存有Session实现。Sessions内部维护一个数据缓存这个缓存随着Session的创建而建立,在Session关闭时将被JVM垃圾回收机制回收除非其还存在引用(即使把其放进一个全局变量中例如集合)。Session内部缓存(说白了也就是Session内部变量)只能在Session实例范围中使用。 2.应用级缓存 缓存在某个应用范围被所有事务共享(指的是数据库事务Session)。缓存的声明周期依赖于应用程序的生命周期,当这个应用程序的生命周期结束时,缓存生命周球随之结束(我们不妨理解为全局变量)。不过这里就存在一个问题,由于缓存
14、被所有事务共享,缓存可能被这些事务并发访问,这个主要必须依靠对缓存设置必要的事务隔离机制和缓存共享策略来尽力避免。另外,应用级缓存在整个应用范围内使用,数据量较大时可以存储在硬盘上。 对于Hibernate而言,应用级别缓存有SessionFactory实现。Session实例有SessionFactory创建,并共享SessionFactory的缓存。 其实我们可以这样理解SessionFactory与Session,以及一级缓存和二级缓存。SessionFactory是一个可执行类的话,二级缓存就相当于其内部的一个集合类作为其全局变量,而Session则可以看做其内部的一个方法(或者是内部
15、方法中的内部类的实例),类的方法肯定是可以访问其类的变量(更何况全局变量),但是类的方法以结束其内部类就会立即消失而类的全局变量则依然存在知道这个类执行完所有方法。因此,如果我们想保存数据库数据副本到二级缓存中,只能在这个类运行内部方法时把带到的数据存到全局变量(比如集合类中)中。缓存是位于应用程序与物理数据源之间,用于临时存放复制数据的内存区域,目的是为了减少应用程序对物理数据源访问的次数,从而提高应用程序的运行性能. Hibernate在查询数据时,首先到缓存中去查找,如果找到就直接使用,找不到的时候就会从物理数据源中检索,所以,把频繁使用的数据加载到缓存区后,就可以大大减少应用程序对物理数据源的访问,使得程序的运行性能明显的提升. Hibernate缓存分类: Session缓存,一级缓存. SessionFactory的缓存分为内置缓存和外置缓存.