首页 > 代码库 > hibernate之缓存
hibernate之缓存
1. 缓存概念:应用数据库访问数据库的代价很高,利用持久化的缓存可以减少与数据库之间的交互,可以从缓存中读取。
注意:缓存使用不当,会造成性能的损失。要在正确使用缓存的前提下,适当情况使用缓存。
2. 持久化缓存的级别:
(1)事务级别:
缓存对象只能被当前事务使用,每个事务都有自己的缓存。事务结束,缓存也结束。
缓存数据以关联对象的形式保存,使用内存作为介质,hibernate的一级缓存即是事务级别。
(2)应用(进程)级别:
可被当前应用(进程)的所有事务访问。
分布式应用不能使用该级缓存,使用内存或硬盘作为储存介质。hibernate的二级缓存可以是此。
(3)分布式级别:
若应用部署在多台服务器的分布式(集群)环境下,数据可被多台服务器共享。
要慎重使用该级别的缓存,多台服务器同步缓存可能会消耗大量的带宽。hibernate的二级缓存也可以是此 。
3. hibernate的一级缓存
(1)概念:是内置缓存,不能人为地取消,也称session缓存。事务级别的缓存,若一次事务多次修改对象,提交时只会执行一条语句,更新所有的修改。
(2)实现原理:可以把一级缓存想象为session对象维护的一个map对象,保存session使用过的对象,session读取数据时先依据对象的类型和标识符属性查找,没有在读数据库,同时保存在map中。
(3)管理一级缓存:
使用session.evict() 方法移除缓存对象,使之变为托管状态。
使用session.clear()方法清除缓存中的所有对象。
使用session的contains()判断是否在一级缓存中, flush()同步数据与数据库一致,setReadOnly()设置为只读对象(不执行脏数据检查)
4. hibernate的二级缓存
(1)概念:由SessionFactory对象管理,应用级别缓存,又称为SessionFactory缓存。会被整个应用的session共享。先一级,在二级。
(2)二级缓存组件:hibernate没有自己的二级缓存组件
组件 | Provider类 | 类型 | 集群 | 查询缓存 |
Hashtable | org.hibernate.cache.HashtableCacheProvider | 内存 | 不支持 | 支持 |
EHCache | org.hibernate.cache.EhCacheProvider | 内存,硬盘 | 不支持 | 支持 |
OSCache | org.hibernate.cache.OSCacheProvider | 内存,硬盘 | 不支持 | 支持 |
SwarmCache | org.hibernate.cache.SwarmCacheProvider | 集群 | 支持 | 不支持 |
JBoss Cache | org.hibernate.cache.TreeCacheProvider | 集群 | 支持 | 支持 |
(3)二级缓存策略:
● 只读缓存(read-only)
如果应用程序需要读取一个持久化类的实例,但并不打算修改它们,可以使用read-only缓存。
对于从来不会修改的数据,如参考数据,可以使用这种并发访问策略。
● 读/写缓存(read-write)
如果应用程序需要更新数据,该缓存比较合适。如果需要序列化事务隔离级别,那么就不能使用这种缓存策略。
若在分布式应用中使用该策略,需要底层的缓存组件支持锁定机制。
● 不严格的读/写缓存(nonstrict-read-write)
如果程序读取频繁且极少更新数据(也就是说,出现两个事务同时更新同一个条目的现象很不常见),也不需要十分严格的事务隔离,适用该缓存。
对于极少被修改,并且允许偶尔脏读的数据,可以采用这种并发访问策略。
● 事务缓存(transactional)
transactional缓存策略提供了对全事务的缓存,仅仅用于JTA环境中。它提供了Repeatable Read事务隔离级别。
(4)管理二级缓存:
SessionFactory对象的evict(Class arg0)方法:
可以从二级缓存中清除指定的持久化类的所有缓存对象,并释放其占用的资源。
如:sessionFactory.evict(Category.class);
SessionFactory对象的evict(Class arg0,Serializable arg1)方法:
可以从二级缓存中清除某个持久化类的指定缓存对象。
如:sessionFactory.evict(Category.class,new Integer(1));
SessionFactory对象的evictCollection(String arg0)方法:
可以从二级缓存中清除指定的集合对象的缓存。
如:sessionFactory.evictCollection("com.hibernate.beans.products");
SessionFactory对象的evictCollection(String arg0,Serializable arg1)方法:
可以从二级缓存中清除集合对象中的指定对象。
如:sessionFactory.evictCollection("com.hibernate.beans.products",new Integer(1));
SessionFactory对象的evictEntity(String arg0)方法:
可以从二级缓存中清除指定的持久化类的所有缓存对象。
如:sessionFacotry.evictEntity("com.hibernate.beans.Category");
SessionFactory对象的evictEntity(String arg0,Serializable arg1)方法:
可以从二级缓存中清除某个持久化类的指定对象。
如:sessionFacotry.evictEntity("com.hibernate.beans.Category",new Integer(1));
5. 查询缓存
查询缓存使用map对象保存被缓存对象,(key值根据sql、查询参数、分页参数等构造)保证同样查询有同样key值;
hibernate会记录每个表的最后更新时间,并且查询缓存也有时间,hibernate会比较这两个时间判断缓存有效性。
6. 缓存对get(), load(), list(), iterator() 方法的影响
(1)get():先从一级缓存,后直接从数据库。缓存到一级缓存。
(2)load():先从一级缓存,再从二级缓存,最后从数据库。缓存到一二级缓存。
(3)Query的list():先检查是否配置查询缓存,在直接从数据库中;缓存到一二级,查询缓存中。
(4) Query的iterator():先从数据库查询所有符合条件的标识符属性值(id),再通过load()方法查询对应数据。
注:本文参考《Hibernate开发与实战》 刘伟 张利国 电子工业出版社 一书
本文出自 “java我的最爱” 博客,请务必保留此出处http://lindianli.blog.51cto.com/7129432/1433809