分类:
2009-03-05 11:28:12
一:hibernate一级缓存
一级缓存很短和session的生命周期一致,一级缓存也叫session级的缓存或事务级缓存
一级缓存是缓存实体对象的,不会缓存普通属性
那些方法支持一级缓存:
* get()
* load()
* iterate(查询实体对象)
如何管理一级缓存:
* session.clear(),session.evict()
如何避免一次性大量的实体数据入库导致内存溢出
* 先flush,再clear
向数据库中批量加入1000条数据
for (int i=0; i<1000; i++) {
Student student = new Student();
student.setName("s_" + i);
session.save(student);
//每20条数据就强制session将数据持久化
//同时清除缓存,避免大量数据造成内存溢出
if ( i % 20 == 0) {
session.flush();
session.clear();
}
}
如果数据量特别大,考虑采用jdbc实现,如果jdbc也不能满足要求可以考虑采用数据本身的特定导入工具
二:hibernate二级缓存
二级缓存是SessionFactory级别的全局缓存,它底下可以使用不同的缓存类库,比如ehcache、oscache等,需要设置hibernate.cache.provider_class,我们这里用ehcache,在2.1中就是 hibernate.cache.provider_class=net.sf.hibernate.cache.EhCacheProvider如果使用查询缓存,加上hibernate.cache.use_query_cache=true
缓存可以简单的看成一个Map,通过key在缓存里面找value。
二级缓存也称进程级的缓存或SessionFactory级的缓存,二级缓存可以被所有的session共享,二级缓存的生命周期和SessionFactory的生命周期一致。hibernate为实现二级缓存,只提供二级缓存的接口供第三方来实现(具体可以查看)。二级缓存也是缓存实体对象 ,其实现原理与一级缓存的差不多吧,其方法与一级的相同,只是缓存的生命周期不一样而已:
* get()
* load()
* iterate(查询实体对象)
其中 Query 和Criteria的list() 只会缓存,但不会使用缓存(除非结合查询缓存)。
二级缓存的配置和使用:
* 将echcache.xml文件拷贝到src下
* 开启二级缓存,修改hibernate.cfg.xml文件
* 指定缓存产品提供商,修改hibernate.cfg.xml文件
* 指定那些实体类使用二级缓存(两种方法)
* 在映射文件中采用
* 在hibernate.cfg.xml文件中,采用
三、查询缓存
查询缓存是针对普通属性结果集的缓存,对实体对象的结果集只缓存id(其ID不是对象的真正ID,它与查询的条件相关即where后的条件相关,不同的查询条件,其缓存的id也不一样) ,查询缓存的生命周期,当前关联的表发生修改或是查询条件改变时,那么查询缓存生命周期结束,它不受一级缓存 和二级缓存 的生命周期的影响,要想使用查询缓存需要手动配置如下:
* 在hibernate.cfg.xml文件中启用查询缓存,如:
* 在程序中必须手动启用查询缓存,如:
query.setCacheable(true);
其中 Query 和Criteria的list() 就可利用到查询缓存了。
管理Hibernate的缓存
Session的缓存是内置的,不能被卸载,也被称为Hibernate的第一级缓存。
SessionFactory有一个内置缓存和一个外置缓存,其中外置缓存是可插拨的缓存插件,也被称为Hibernte的第二级缓存。
缓存的实现不仅需要作为物理介质的硬件,同时还需要用于管理缓存的并发访问和过期等策略的软件。因此,缓存是通过软件和硬件同时实现的。
1. Hibernate的Session的缓存中存发的数据是数据库中数据的拷贝。在数据库数据表现为关系数据形式,而在Session的缓存中数据表现为相互关联的对象。在读写数据库时,Session会负责这两种形式的数据的映射。Session在某些时间点会按照缓存中的数据来同步更新数据库,这一过程称为清理缓存。
2.SessionFactory的缓存可分为两类:内置缓存和外置缓存。SessionFactory的内置还促和Session的缓存在实现方式上比较相似,前者时指SessionFactory对象的一些集合属性宝航的数据,后者是指Session的一些集合属性。SessionFactory的内置缓存中村发了映射员数据和预定义SQL语句,映射员数据是映射文件中数据的拷贝,而预定义SQL语句是在Hibernate初始化阶段根据映射元数据到出来的。SessionFactory的内置缓存是制度缓存,应用不能修改缓存中映射元数据和预定义的SQL语句,SessionFactory无需进行内置缓存与映射文件的同步。
3.SessionFactory的外置缓存和Session
比较Hibernate的第一级缓存和第二级缓存的区别
区别之处 |
第一级缓存 |
第二级缓存 |
存放数据的形式 |
相互关联的持久化对象 |
对象的散装数据 |
缓存范围 |
事务范围,每个事务拥有单独的第一级缓存 |
进程或群级范围,缓存被同一个进程或群级范围内的所有事务共享 |
并发访问策略 |
由于每个事务都拥有单独的第一级缓存,不会出现并发问题,因此无需提供并发访问策略 |
由于多个事务会同时访问第二级缓存中相同数据,因此必须提供适当的并发访问策略,来保证特定的事务隔离级别 |
数据过期策略 |
没有提供过期策略处于第一级缓存中的对象永远不会过期,除非应用程序显示清空缓存或者清除特定的对象。 |
必须提供数据过期策略,如基于内存的缓存中的对象最大数目,允许对象处于缓存中的最长时间,以及允许对象处于缓存中的最大空闲时间。通过maxElementsInMemory等 进行设置。 |
物理介质 |
内存 |
内存和硬盘 |
缓存的软件实现 |
Session的实现中包含了缓存的实现 |
由第三方提供,Hibernate仅提供一些缓存适配器。 |
启用缓存的方式 |
通过Session接口执行保存、更新等操作,Hibernate就会启用第一级缓存,把数据库中的数据以对象的形式拷贝到缓存中。 |
可通过单个集合的粒度上配置第二级缓存。如果类的实例被经常读但很少修改,就可以考虑第二级缓存。只要为某个类或集合配置了第二级缓存,Hibernate在运行时才会把它的实例加入第二级缓存 |
用户管理缓存的方式 |
由于内存的容量有限,必须通过恰当的检索策略和检索方式来限制加载对象的数目。Session的evit()可以显示清空缓存中特定对象,但不推荐这种方法 |
可以存放大量的数据,数据过期策略的maxElementsInMemory属性值可以控制内存中的对象数目。管理:选择需要使用第二级缓存的持久化类,设置合适的并发访问策略;选择合适的缓存适配器,设置合适的过期策略。SessionFactory的evit()也可以显示清空缓存中特定对象,但不推荐这种方法。 |