每个session有一个一级缓存,session打开,一级缓存创建,session关闭,一级缓存就销毁。
当使用get或load方法按id查询对象时,首先查询缓存中是否有此对象:
有,直接返回此对象;
没有,才查询数据库,并将查询到的对象放入一级缓存。
如果是用hql语句查询,则会绕过一级缓存,但要注意,hql的查询结果会被打散了放入一级缓存,即hql查询的集合结果不会整体放入一级缓存,但集合中每个元素会被放入以及缓存
使用hibernate新增一万个对象,经常会出现内存耗尽异常,如何解决?
原理: Session session = ...;
session.beginTransaction();
for(int i = 0; i < 10000; i++){
City c = new City();
c.setName("城市" + i);
session.save(c);
}
// 循环完毕,内存中存储了一万个city对象,导致内存占用高
session.getTransaction().commit();
解决:
Session session = ...;
session.beginTransaction();
for(int i = 0; i < 10000; i++){
City c = new City();
c.setName("城市" + i);
session.save(c);
session.flush(); // 循环一次,立刻执行insert语句
session.evict(c); // 并从一级缓存中清除该对象
}
// 循环完毕,一级缓存仍是空的,不会占用太多内存
session.getTransaction().commit();
session flush在commit之前默认都会执行他。也可以手动执行它,主要做了两件事:
1) 清理缓存。
2) 执行SQL。
原文地址:http://liuyj.blog.51cto.com/2340749/1693653