Hibernate缓存机制-总结
缓存: 是临时存放复制数据的内存区域(Hibernate 分持久化对象和ID列表)
缓存作用:查询数据时,首先到缓存中去查找,减少数据库的SQL访问
>一级缓存,二级缓存和查询缓存都打开的情况下作查询操作时这样的:
查询普通属性,会先到查询缓存中取,如果没有,则查询数据库;
查询实体,会先到查询缓存中取id,如果有,则根据id到缓存(一级/二级)中取实体,如果缓存中取不到实体,再查询数据库
缓存实体对象:(一级缓存,二级缓存)
缓存普通属性: (查询缓存)(HQL和SQL是查询属性级别-针对条件查询的Query缓存)
二级缓存和查询缓存都相当于一个map
二级缓存的key为id,value为实体对象
查询缓存的key为sql语句及一些相关信息,value为id列表
_一级缓存很短和session的生命周期一致,一级缓存也叫session级的缓存或事务级缓存
支持一级缓存:
* get()
* load()
* iterate(查询实体对象)
如何管理一级缓存:
clear() 一级缓存中的所有持久化对象清除,释放内存资源
evit(Object obj) 将指定的持久化对象从一级缓存中清除,成为游离对象
contains(Object obj) 判断指定的对象是否存在于一级缓存中
如何避免一次性大量的实体数据入库导致内存溢出
* 先flush,再clear
如果数据量特别大,考虑采用jdbc实现
po->vo
session.save(user); // VO经过Hibernate进行处理成PO
TUser user = (TUser)session.load(TUser.class,new Integer(1)); //返回po
session.close(); //po->vo
如果使用TransactionAPI,在事务提交的时候,隐含就会包括这一步。否则,调用session.flush()
session.flush(); // 确保你所有的修改被持久化到数据库
session.clear();// Hibernate占用的内存就释放掉了
_二级缓存
二级缓存也称进程级的缓存或SessionFactory级的缓存,二级缓存可以被所有的session共享
二级缓存的生命周期和SessionFactory的生命周期一致,SessionFactory可以管理二级缓存
二级缓存保存已经读出的对象在各个事务之间的Session Factory级别
Hibernate的二级缓存功能是靠缓存插件来实现的,提供org.hibernate.cache.CacheProvider接口
常用的二级缓存插件 EHCache OSCache
hibernate.cache.use_second_level_cache属性,它可以让你启用(和关闭)二级缓存
合适加载到二级缓存中:
1.数据更新频率低 (常量基础数据)
2.不会被并发访问
3.共享数据
释放二级缓存
sessionFactory.evict(Class arg0, Serializable arg1)
_一级缓存vs二级缓存
都位于持久层,区别就是缓存范围不一样
缓存的范围分为3类:
1.(事务范围)一级缓存是事务级缓存
2.(应用范围)SessionFactory级的二级缓存可以被所有的session共享
3.(集群范围) 集群环境中的每个进程间通过远程通信来保证缓存中的数据的一致(二级缓存是进程级的缓存)
_查询缓存
List()需要开启查询缓存,第二次查询这条语句时就会去根据sql语句及相关信息去key里找id列表取出一个一个load(),
接下来就和iterate一样了。List一般只有第一次发发出取实体列表的语句,以后的id列表就会去查询缓存取id列表,不会再发出sql语句。
所以,对于实体的查询,须结合二级缓存使用
所以,对象缓存超时时间不能短于查询缓存设置的超时时间
query = session.createQuery("select s.name from Student s");
//启用查询查询缓存
query.setCacheable(true);
//没有发出查询sql,因为启用了查询缓存
names = query.list();
for (Iterator iter=names.iterator();iter.hasNext(); ) {
String name = (String)iter.next();
System.out.println(name);
}