hibernate缓存按照大类分包括事物级别的缓存(session),应用级的缓存(sessionFactory),分布式的缓存
事物级别的缓存是基于session的声明周期实现的。session内部会存在这样的一个缓存。
应用级别的缓存:实际上是基于插件实现的,就是sessionFactory上的缓存。也是我们熟称的二级缓存。
分布式的缓存就是多个应用实例,多个JVM之间共享的缓存策略,通过远程机制实现各个缓存实例之间的数据同步。
hibernate的缓存细分分为对象缓存和查询缓存,查询缓存必须以对象缓存作为基础才能起作用否则效率会很低。
对象缓存是缓存查询的实体对象到内存。这样下次查找的时候就会直接去缓存查找对象从而避免了去数据库获取。
查询缓存实际上是缓存了关联对象的id,而后会根据这个id去对象缓存中查找实体对象,若是查不到再去查询数据库。
hibernate中二级缓存是以插件的方式实现的。
hibernate3默认的二级缓存使用的是EhCache。
hibernate3版本中的二级缓存配置如下
Hibernate.cfg.xml
启用class缓存:
<property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
启用查询缓存:
<property name="hibernate.cache.use_query_cache">true</property>
如果spring集成hibernate时,配置二级缓存的方式如下
启用class缓存:
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider
</prop>
启用查询缓存:
<prop key="hibernate.cache.use_query_cache">true</prop>
配置ehcache,将ehcache.xml放到classpath下面
配置样式如下:
<diskStore path="java.io.tmpdir" />
<!--默认的缓存配置 -->
<defaultCache maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" />
<!-- 如果需要对某个类特殊配置按照如下的方式,sampleCache1代表实体类的全路径 -->
<cache name="sampleCache1" maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true" />
<!-- 如果需要为查询缓存单独配置按照下民的方式,否则默认会让查询缓存使用默认的缓存策略 -->
<cache name="org.hibernate.cache.UpdateTimestampsCache"
maxElementsInMemory="5000" eternal="true" timeToIdleSeconds="1800"
timeToLiveSeconds="0" overflowToDisk="true" />
<cache name="org.hibernate.cache.StandardQueryCache"
maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="1800"
timeToLiveSeconds="0" overflowToDisk="true" />
<!-- 注意事项
“当hibernate更新数据库的时候,它怎么知道更新哪些查询缓存呢? hibernate在一个地方维护每个表的最后更新时间,其实也就是放在上面UpdateTimestampsCache所指定的缓存配置里面。
当通过hibernate更新的时候,hibernate会知道这次更新影响了哪些表。然后它更新这些表的最后更新时间。每个缓存都有一个生成时间和这个缓存所查询的表,当hibernate查询一个缓存是否存在的时候,如果缓存存在,它还要取出缓存的生成时间和这个缓存所查询的表,然后去查找这些表的最后更新时间,如果有一个表在生成时间后更新过了,那么这个缓存是无效的。
可以看出,只要更新过一个表,那么凡是涉及到这个表的查询缓存就失效了,因此查询缓存的命中率可能会比较低。”
-->
对对象使用二级缓存,两种方式
即在映射文件中或是使用注解
映射文件中:
<class name="Product" table="product" >
<cache usage="read-write"/> <id name="id" type="java.lang.Integer">
<column name="id"/>
<generator class="increment"/>
</id>
<property name="name" type="java.lang.String"/>
<property name="pDesc" type="java.lang.String"/>
<property name="orderId" type="java.lang.Integer"/>
</class>
注解的方式:
@Entity
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Forest { ... }
对于session级别的缓存如果使用get方式会只执行一条,如果关闭了session会执行多条
对对象的关联结合进行二级缓存,需要在配置文件中进行。且只对onetomany有效,只会缓存关联集合的对象ID,如果要完全缓存关联对象需要对关联对象也进行二级缓存
配置如下:
<set name="children" lazy="true" order-by="treeid asc">
<cache usage="read-write"/>
<key column="PARENTID"/>
<one-to-many class="SysCodelist"/>
</set>
集合缓存是独立的,不受关联对象的删除、修改的影响。
无论是list,load,iterator查询出的对象都会放入class缓存
当修改某个对象,hibernate会根据id从缓存中移除该对象。
ehcache缓存的策略有:
read-only
read-write
nonstrict-read-write 不严格的读写,即任务两个事物更新同一个记录可能性比较小,性能会比read-write好一些
事务缓存(transactional):当发生异常时可以回滚,只用于jta的方式。
读写缓存会读要操作的缓存数据进行加锁,若是其他事物要操作该数据时发现加锁了就要去查询数据库。不严格读写缓存不锁住缓存中的数据。
查询缓存:查询缓存的目的就是为了通过list()方法的查询结果放入缓存中,并实现对语句的缓存,如果下次用户使用同样的查询语句的时,会直接从查询结果中获取对象的数据。
可见查询缓存实际上是缓存了以sql语句为key,查询结果为value的。
当第一次启用查询缓存的session进行语句查询的时候,系统只执行一次将全部的查询对象取出,然后放入class缓存。语句和id集合存入查询缓存。而当第二次执行相同语句的查询时,先会去查询缓存中查找,如果有,就取出每个对象id去class缓存中查找,若是此时对象的缓存没有启动或是过期,那么session活根据id一个个的load,就会出现select N+1的问题。
实际开发中并不是对所有的对象进行二级缓存的。但是spring中提供的hibernate方法虽然有getHibernateTemplate().setCacheQueries(),但是影响是全局的。一旦启用将会对不需要缓存的查询照成不良的影响。
因此可以自己写一个方法
public List findByCachedQuery(final String hql)
{
return (List) getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
Query queryObject = session.createQuery(hql);
queryObject.setCacheable(true);
if (getHibernateTemplate().getQueryCacheRegion() != null) {
queryObject.setCacheRegion(getHibernateTemplate().getQueryCacheRegion());
}
return queryObject.list();
}
}, true);
}
将只在session范围内启用查询缓存。
一旦session结束那么查询缓存也恢复到默认配置。
注意如果使用二级缓存,那么所有对数据库的修改都要走hibernate,如果使用sql将会对二级缓存没有影响,会让二级缓存与数据数据不一致。
如果调用存储过程,hibernate也是不会知道的
在配置文件中打开查询二级缓存的方式:
hibernate.cache.use_query_cache true
显示编程设置二级缓存
对query的的方法
List blogs = sess.createQuery("from Blog blog where blog.blogger = :blogger") .setEntity("blogger",blogger) .
setMaxResults(15) .
setCacheable(true) .
setCacheRegion("frontpages") .
list();
注意session.find()方法永远去查询数据库,不会去二级缓存中查找数据的
使用hibernate二级缓存的主要原因是因为hibernate的session缓存声明周期非常短,
session缓存主要的作用是为了保存session中的数据与数据库的同步。
因此对系统性能的提升非常少。所以为了提升系统的性能常常使用了
延迟加载、模切外链接、查询过滤。还需要配置二级缓存。
hibernate的iterator有著名的N+1问题,但是通常只有第一次加载的时候有这样的问题。
后面的性能会得到极大的提升。该方法适用于查询数据量较大的情况。
但是对数据量特别大的数据,如流水数据需要指定特殊的缓存策略。以防止大量数据载入内存导致的内存溢出。
使用hibernate的hql语句和save等方法更新数据的同时也会更新缓存中的数据。
分享到:
相关推荐
**Hibernate缓存深入详解** 在Java企业级应用开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。然而,随着应用规模的扩大,数据访问性能成为了一个不可忽视的问题。这时,...
### Hibernate缓存技术研究 #### 一、引言 Hibernate是一种强大的对象-关系映射(Object-Relational Mapping,简称ORM)工具,主要用于Java环境下的应用程序。它能够将应用程序中的对象模型映射到关系型数据库的表...
Hibernate缓存.docHibernate缓存.doc
Java Hibernate缓存深入详解
### Hibernate缓存机制及优化策略 #### 一、概述 Hibernate作为一款优秀的对象关系映射(ORM)框架,在Java开发领域被广泛应用于数据库操作。它提供了丰富的缓存机制来提高应用性能并降低数据库访问压力。本文将...
**标题:“Hibernate缓存与Spring事务详解”** 在IT领域,尤其是Java开发中,Hibernate作为一款流行的ORM(对象关系映射)框架,极大地简化了数据库操作。而Spring框架则以其全面的功能,包括依赖注入、AOP(面向切...
Hibernate缓存机制是提高应用程序性能的关键技术之一,它通过存储数据副本减少对物理数据库的访问。缓存可以分为两层:第一级缓存和第二级缓存。 **第一级缓存**是内置在Session中的,它是不可卸载的,也称为...
关于hibernate缓存的一个ppt课件,60+幻灯片,有需要的可以看一下
【Hibernate缓存深入详解】 在Java的持久化框架Hibernate中,缓存机制是提升系统性能的关键因素。它位于Hibernate应用和数据库之间,减少了对数据库的直接访问,从而提高了应用程序的运行速度。缓存中存储的是...
**Hibernate缓存详解** 在Java开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。为了提高数据访问性能,Hibernate引入了缓存机制,它可以减少对数据库的直接访问,从而提升应用的...
本文将深入探讨Hibernate缓存的原理、类型及其对性能优化的影响。 ### Hibernate缓存原理 Hibernate缓存主要分为一级缓存和二级缓存。一级缓存,也称为会话缓存(Session Cache),是默认启用的,由Hibernate自动...
Hibernate 是一个流行的对象关系映射(ORM)框架,它允许Java...通过理解Hibernate缓存和事务管理,以及如何有效地执行查询,开发者可以创建高效、健壮的Java应用程序,降低与数据库交互的复杂性,同时提升系统性能。
**标题解析:** "Hibernate教程25_Hibernate缓存" 这个标题表明了我们要讨论的是关于Hibernate框架的第25个教程,重点是它的缓存机制。Hibernate是一个流行的Java对象关系映射(ORM)框架,它允许开发者用面向对象的...
【Hibernate缓存管理】是数据库持久化框架Hibernate中优化性能的关键技术。缓存的主要目的是减少对数据库的直接访问,提高应用程序的运行效率。缓存的数据是数据库中数据的副本,存在于内存或硬盘中,便于快速读取。...
这篇博客文章“hibernate缓存ehcache用法”可能详细介绍了如何在Hibernate中配置和使用Ehcache。 首先,我们需要理解什么是缓存。缓存是一种存储技术,用于临时保存经常访问的数据,以减少对主存储器(如数据库)的...
【Hibernate缓存详解】 在Java开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。其缓存机制是提升系统性能的关键所在。本篇将深入探讨Hibernate的缓存机制,包括一级缓存和二级...