作者:Duncan from Hour41 (www.hour41.com)
Hibernate缓存是一种提高系统性能的比较好的工具,如果使用合理,则能极大地提高系统性能,但如果使用不合理也会使用系统性能下降。Hibernate缓存比较复杂,要想灵活使用hibernate缓存,必须深入研究hiberante缓存原理,最好能分析hibernate的源代码。有很多人使用hibernate的时间比较长也不能正确理解hibernate缓存,下面我就谈谈hibernate缓存的使用,希望能对大家有点帮助。
Session缓存(一级缓存):当调用Session的保存、更新、查询操作时,在Session缓存中不存在相应对象,则把这些对象加入Session缓存。同一个Session操作,第一次通过ID调用load()或get()查询持久对象,先从Session缓存中查询发现该对象不命中,随即发送一条SQL语句生成一个持久对象并把该对象放入Session缓存。第二次再通过相同ID调用load()或get()查询时将直接从Session缓存将该对象返回,避免多余的数据库连接和查询的开销。
Session的load()和get()方法使用区别:
1、当数据库不存在对应ID数据时,调用load()方法将会抛出ObjectNotFoundException异常,get()方法将返回null,我比较喜欢使用get()方法。
2、当对象.hbm.xml配置文件<class>元素的lazy属性设置为true时,调用load()方法时则返回持久对象的代理类实例,此时的代理类实例是由运行时动态生成的类,该代理类实例包括原目标对象的所有属性和方法,该代理类实例的属性除了ID不为null外,所在属性为null值,查看日志并没有Hibernate SQL输出,说明没有执行查询操作,当代理类实例通过getXXX()方法获取属性值时,Hiberante才真正执行数据库查询操作。当对象.hbm.xml配置文件<class>元素的lazy属性设置为false时,调用load()方法则是立即执行数据库并直接返回实体类,并不返回代理类。而调用get()方法时不管lazy为何值,都直接返回实体类。
3、load()和get()都会先从Session缓存中查找,如果没有找到对应的对象,则查询Hibernate二级缓存,再找不到该对象,则发送一条SQL语句查询。关于这点,很多资料说明get ()不会查询二级缓存,比如夏昕编著的《深入浅出Hibernate》245页描述get()方法不查询二级缓存。但我测试发现load()和get()方法都会查询二级缓存,我上网看了很多缓存方面资料也证实了这点,大家可以看看这篇文章:http://blog.csdn.net/woshichenxu/archive/2006/01/22/586361.aspx
Session的evict()方法将持久对象从Session缓存中清除,clear()方法将清空整个缓存。
二级缓存(SesionFactory): 二级缓存由SessionFactory创建的所有Session对象共享使用, 二级缓存可使用第三方的缓存插件,如EHCache、OSChahe、SwarmCache、JBossCache,下面分别介绍二级缓存的类缓存、集合缓存和查询缓存。
1、类缓存:类缓存的key是持久对象的ID,value为持久化对象POJO,无论调用list(),load()还是iterate()查询,只要读出一个持久化对象POJO,都会根据POJO的ID作为key,value为POJO填充到类缓存中。当通过iterate()方法查询时,先会向数据库发送一条select id from POJO的SQL语句,将所有ID查询出来,再根据ID一个个地作为key到类缓存中查询相应POJO,如果类缓存中存在(命中),则从缓存中返回,否则向数据库发一条select * from POJO where id=?语句将查询该对象返回,并填充到类缓存中。当通过list()方法查询时,不会象iterate()先查询ID再查询类缓存,而是直接发送SQL查询数据库将结果返回,但会将查询结果填充到类缓存中,可供itetator()使用。
配置类缓存的同步策略:在hibernate中启动二级类缓存,需要在hibernate.cfg.xml配置以下参数:
<hibernate-configuration>
<session-factory>
……
<property name=”hibernate.cache.provider_class”>
org.hibernate.cache.EhCacheProvider
<./property>
</session-factory>
</hibernate-configuration>
在这里以EHCache配置为例,如果用spring的applicationContext.xml配置,参数为:
<beans>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
……
<property name="hibernateProperties">
……
<prop key="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</prop>
……
</bean>
</beans>
在这还需要对EHCache进行配置,ehcache.xml配置为:
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="10000"
timeToLiveSeconds="10000"
overflowToDisk="true"
/>
<cache name="com.hour41.hibernate.vo.common.City"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="10000"
timeToLiveSeconds="10000"
overflowToDisk="true"
/>
</ehcache>
上面配置了默认类缓存和城市类缓存策略:
<diskStore>表示当内存缓存中对象数量超过类设置内存缓存数量时,将缓存对象写到硬盘,path=”java.io.tmpdir”表示把数据写到这个目录下。Java.io.tmpdir目录在运行时会根据相对路径生成。
<defaultCache>表示设定缓存的默认数据过期策略。
<cache>表示设定用具体的命名缓存的数据过期策略。
name表示具体的缓存命名。
maxElementsInMemory表示cache中最大允许保存的对象数据量。
eternal表示cache中数据是否为常量。
timeToIdleSeconds表示缓存数据钝化时间
timeToLiveSeconds表示缓存数据的生命时间。
overflowToDisk表示内存不足时,是否启用磁盘缓存。
Hibernate提供了四种缓存同步策略:
read-only策略:只读,对于数据库表的数据不会改变的数据,可以使用只读型缓存。例如城市表的数据不会发生变化,则可配置类缓存为:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.hour41.hibernate.vo.common.City" table="tbl_city" lazy="false" mutable="false">
<cache usage="read-only" />
<id name="id" type="java.lang.Integer">
<column name="cityId" />
<generator class="native"></generator>
</id>
<property name="cnName" type="java.lang.String">
<column name="cityCnName"/>
</property>
<property name="enName" type="java.lang.String">
<column name="cityEnName"/>
</property>
<property name="provinceId" type="java.lang.Integer">
<column name="provinceId" />
</property>
</class>
</hibernate-mapping>
nonstrict-read-write策略:如果程序对并发数据修改要求不是非常严格,只是偶尔需要更新数据,可以采用本选项,以减少无谓的检查,获得较好的性能。
read-write策略:严格可读写缓存。
transactional策略:事务型缓存。
暂时先写到这里,如果了解更多二级缓存的使用,请先关注我的“谈谈Hibernate缓存使用(二)”,将介绍集合缓存、查询缓存使用和我使用hibernate缓存的一些经验。
相关推荐
接下来,我们谈谈Hibernate。Hibernate是一个开源的ORM框架,将Java对象与数据库表对应,使得开发者可以使用面向对象的方式来操作数据库。它的主要优点包括: 1. 解耦:ORM层将业务逻辑与数据库访问分开,降低了...
首先,让我们谈谈Hibernate的基本概念。ORM框架是为了解决程序中的数据持久化问题,即如何将业务对象(如Java类)与数据库表进行映射,使得开发者可以像操作对象一样操作数据库。Hibernate提供了一种直观、高效的...
接下来,我们谈谈Hibernate与数据库事务的关系。在Hibernate中,通常一个Session对应一个数据库事务。默认情况下,Flush操作会在事务提交前进行,确保事务内的所有操作都能正确反映到数据库。如果在事务中遇到异常,...
最后,关于“工具”这个标签,虽然这里没有具体提到是哪种工具,但在使用Hibernate的开发环境中,例如IDEA或Eclipse,这些集成开发环境通常都有对Hibernate的支持,包括自动完成、代码提示和调试功能,这些工具可以...
除此之外,Hibernate还提供了缓存机制,如一级缓存(Session级缓存)和二级缓存(SessionFactory级缓存),以提高性能。此外,还有第三方缓存服务,如 Ehcache 和 Memcached,它们可以进一步提升系统的响应速度。 ...
在IT领域,Hibernate是一个非常重要的Java持久化框架,它简化了数据库操作,使得开发者能够更加专注于业务逻辑,而不是繁琐的数据存取。本话题主要聚焦于`Hibernate02`,涵盖`Session`对象、HQL(Hibernate Query ...
接下来,我们谈谈Hibernate。Hibernate作为ORM框架,使得Java开发者可以使用面向对象的方式来操作数据库,无需编写繁琐的SQL语句。它通过映射Java类到数据库表,将对象和关系数据库之间建立桥梁,使得数据操作更加...
接下来,我们谈谈Hibernate。Hibernate作为ORM框架,通过映射Java类和数据库表,使得开发者无需编写SQL语句就能进行数据库操作。它提供了Session接口,用于执行CRUD操作,事务管理和缓存管理。实体类通过@Entity注解...
而Hibernate则是一款优秀的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者可以使用面向对象的方式处理数据。Redis则是一款高性能的内存数据存储系统,常被用作缓存或消息中间件。在现代Web应用中,Spring...
1.9. hibernate如何管理缓存 4 1.10. 使用Hibernate的优点: 6 1.11. Hibernate是如何延迟加载? 6 1.12. Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系) 6 1.13. Hibernate的查询方式 7 1.14. 如何...
4. **谈谈Hibernate的缓存机制**(一级缓存、二级缓存,以及第三方缓存集成) 5. **如何解决Hibernate的级联操作引发的效率问题**(合理设置fetch mode,避免不必要的查询) 掌握SSH框架不仅有助于开发者理解MVC...
再来谈谈Hibernate3,它是Java领域的一款对象关系映射(ORM)工具,用于简化数据库操作。在虚拟股票交易系统中,Hibernate3将数据库表与Java对象进行映射,使得开发者可以像操作普通对象一样操作数据库记录,大大...
Hibernate提供了CRUD(Create、Read、Update、Delete)操作,使得数据库的增删改查变得简单易行,同时支持事务管理和缓存机制,提高了系统的性能。 在“UserProject3”这个压缩包中,包含了项目的源代码和相关的...
### Java框架面试题总结 #### Struts篇 **1.... ... 谈谈Hibernate中inverse的作用** `inverse`属性用于指定关联关系的维护方,即哪一方负责更新关联关系。 **12. hibernate中对象的三种状态** -...
SSH2+DWR小图书管理系统是一个适合初学者的实践项目,它结合了Spring、Struts2和Hibernate这三个框架,以及Direct Web Remoting (DWR) 技术,为用户提供了一个简单但功能完整的图书管理解决方案。下面将详细讲解SSH2...
为了设计一个高性能的搜寻引擎,需要使用分布式架构、负载平衡、缓存机制等技术来实现。 11. 公司级应用有哪些特别要求?在何种状况下我们不需要考虑这些要求? 公司级应用的特别要求包括高可用性、高性能、安全性...
1. 数据库连接管理:使用JDBC(Java Database Connectivity)进行数据库操作,或者使用ORM(对象关系映射)框架如Hibernate或MyBatis,将数据库操作与业务逻辑解耦。 2. MVC(模型-视图-控制器)架构:库存管理系统...
如果不使用Hibernate自带的分页,则采用什么方式分页? 62 71.16. hibernate中一对多配置文件返回的是什么? 63 71.17. hibernate拒绝连接、服务器崩溃的原因?最少写5个 63 71.18. Hibernate主键介绍 63 71.18.1. ...
再来谈谈Ajax框架的JAR包,如jQuery库的jquery.js,它是一个广泛使用的JavaScript库,提供了丰富的DOM操作、事件处理和动画效果。而像 Prototype.js 或 Dojo Toolkit 这样的其他框架,也提供了异步通信功能,使得...