二级缓存
Hibernate 对数据的缓存包括两个级:[color=red]一级缓存,在Session的级别上进行,主要是[b]对象缓存[/b],以其id为键保存对象,在Session的生命期间存在;二级缓存,在SessionFactory的级别上进行,有[b]对象缓存和查询缓存[/b],查询缓存以查询条件为键保存查询结果,在SessionFactory的生命期间存在。[/color]默认地,Hibernate只启用一级缓存,通过正确地使用二级缓存,往往可以获得意想不到的性能。
1)对象缓存:
[color=red]当抓取一个对象之后,Hiberate将其以id为键缓存起来,当下次碰到抓取id相同的对象时,可以使用如下配置[/color] 方法1:在缓存对象上配置
<class ...>
<cache useage="read-only/write/...." regions="group" />
</class>
useage 表示使用什么类型的缓存,譬如只读缓存、读写缓存等等(具体参见Hibernate参考指南),值得注意的时,有部分缓存在Hibernate的实现中不支持读写缓存,譬如JBossCache在Hibernate的实现中只是一种只读缓存,具体缓存实现对缓存类型的支持情况,可以参见 org.hibernate.cache包
regions表示缓存分块,大部分的缓存实现往往对缓存进行分块,该部分是可选的,详细参见各缓存实现
方法2:在hibernate.cfg.xml中配置
<cache class=".." useage=".." regions=".."/>
我认为第二种更好,可以统一管理
2)查询缓存
[color=red]查询时候将查询结果以查询条件为键保存起来[/color],需要配置如下
A.在hibernate.cfg.xml中配置(启用查询缓存)
<property name="hibernate.cache.use_query_cache">true</property> (前面的属性名可参见常量
org.hibernate.cfg.Enviroment.USE_QUERY_CACHE)
B.程序
query.setCacheable(true);
query.setCacheRegions(...);
需要注意的是,查询缓存与对象缓存要结合更有效,因为查询缓存仅缓存查询结果列表的主键数据
一般情况下在开发中,对一些比较稳定而又被频繁引用的数据,譬如数据字典之类的,将其进行二级缓存,对一些查询条件和查询数据变化不频繁而又常常被使用的查询,将其进行二级缓存。由于二级缓存是放在内存中,而且Hibernate的缓存不是弱引用缓存(WeekReference),所以注意不要将大块的数据放入其中,否则可能会被内存造成比较大的压力。
3.批量数据操作
[color=red]当进行大批量数据操作(几万甚至几十几百万)时,需要注意两点,一,批量提交,二,及时清除不需要的一级缓存数据[/color] 1)所谓的批量提交,就是不要频繁使用session的flush,每一次进行flush,Hibernate将PO数据于数据库进行同步,对于海量级数据操作来说是性能灾难(同时提交几千条数据和提交一条数据flush一次性能差别可能会是几十倍的差异)。一般将数据操作放在事务中,当事务提交时 Hibernate自动帮你进行flush操作。
2)及时清除不需要的一级缓存数据:[color=red]由于Hibernate默认采用一级缓存,而在 session的生命期间,所有数据抓取之后会放入一级缓存中,而当数据规模比较庞大时,抓取到内存中的数据会让内存压力非常大,一般分批操作数据,被一次操作之后将一级缓存清除,譬如
session.clear(User.class) 或者 session. Evict(Object)[/color]
Hibernate 对数据的缓存包括两个级:[color=red]一级缓存,在Session的级别上进行,主要是[b]对象缓存[/b],以其id为键保存对象,在Session的生命期间存在;二级缓存,在SessionFactory的级别上进行,有[b]对象缓存和查询缓存[/b],查询缓存以查询条件为键保存查询结果,在SessionFactory的生命期间存在。[/color]默认地,Hibernate只启用一级缓存,通过正确地使用二级缓存,往往可以获得意想不到的性能。
1)对象缓存:
[color=red]当抓取一个对象之后,Hiberate将其以id为键缓存起来,当下次碰到抓取id相同的对象时,可以使用如下配置[/color] 方法1:在缓存对象上配置
<class ...>
<cache useage="read-only/write/...." regions="group" />
</class>
useage 表示使用什么类型的缓存,譬如只读缓存、读写缓存等等(具体参见Hibernate参考指南),值得注意的时,有部分缓存在Hibernate的实现中不支持读写缓存,譬如JBossCache在Hibernate的实现中只是一种只读缓存,具体缓存实现对缓存类型的支持情况,可以参见 org.hibernate.cache包
regions表示缓存分块,大部分的缓存实现往往对缓存进行分块,该部分是可选的,详细参见各缓存实现
方法2:在hibernate.cfg.xml中配置
<cache class=".." useage=".." regions=".."/>
我认为第二种更好,可以统一管理
2)查询缓存
[color=red]查询时候将查询结果以查询条件为键保存起来[/color],需要配置如下
A.在hibernate.cfg.xml中配置(启用查询缓存)
<property name="hibernate.cache.use_query_cache">true</property> (前面的属性名可参见常量
org.hibernate.cfg.Enviroment.USE_QUERY_CACHE)
B.程序
query.setCacheable(true);
query.setCacheRegions(...);
需要注意的是,查询缓存与对象缓存要结合更有效,因为查询缓存仅缓存查询结果列表的主键数据
一般情况下在开发中,对一些比较稳定而又被频繁引用的数据,譬如数据字典之类的,将其进行二级缓存,对一些查询条件和查询数据变化不频繁而又常常被使用的查询,将其进行二级缓存。由于二级缓存是放在内存中,而且Hibernate的缓存不是弱引用缓存(WeekReference),所以注意不要将大块的数据放入其中,否则可能会被内存造成比较大的压力。
3.批量数据操作
[color=red]当进行大批量数据操作(几万甚至几十几百万)时,需要注意两点,一,批量提交,二,及时清除不需要的一级缓存数据[/color] 1)所谓的批量提交,就是不要频繁使用session的flush,每一次进行flush,Hibernate将PO数据于数据库进行同步,对于海量级数据操作来说是性能灾难(同时提交几千条数据和提交一条数据flush一次性能差别可能会是几十倍的差异)。一般将数据操作放在事务中,当事务提交时 Hibernate自动帮你进行flush操作。
2)及时清除不需要的一级缓存数据:[color=red]由于Hibernate默认采用一级缓存,而在 session的生命期间,所有数据抓取之后会放入一级缓存中,而当数据规模比较庞大时,抓取到内存中的数据会让内存压力非常大,一般分批操作数据,被一次操作之后将一级缓存清除,譬如
session.clear(User.class) 或者 session. Evict(Object)[/color]