Hibernate3中Session缓存即一级缓存
概述
什么是Session缓存
Hibernate的一级缓存是由Session提供的,因此它存在于Session的整 个生命周期中,当程序调用save()/update()/saveOrupdate()/get()等及 查询接口方法list()/iterator()方法时候,如果session中不存在该对象, 那么会先将本次的对象存储到一级缓存中便于以后使用,当Session关 闭时同时清空一级缓存数据。clear()/evict()
Session缓存的作用
减少访问数据库的次数,进而提高效率。保证缓存中的对象与数据库的记录保持 同步,当缓存的对象改变后,session不会立即执行sql,而是将多个sql语句合并 为一条sql进行执行,提高效率。
Session的缓存举例 的缓存举例
当用户需要对指定的对象进行修改的时候,如果对于同一个属性修改了多次,其 实hibernate的session缓存并不是执行多个update语句,而是以最后一个更新为 准而发送一条更新的sql。
特点
只在(当前)session范围有效,作用时间短,效果不是特别明显!
在短时间内多次操作数据库,效果比较明显!
缓存相关几个方法的作用
- session.flush(); 让一级缓存与数据库同步
- session.evict(arg0); 清空一级缓存中指定的对象
- session.clear(); 清空一级缓存中缓存的所有对象
在什么情况用上面方法?
- 批量操作使用使用:
- Session.flush(); // 先与数据库同步
- Session.clear(); // 再清空一级缓存内容
实例
Get ()先将获取的对象存储到一级缓存,当再次加载同 一个持久化对象的时候先检测一级缓存中是否有该对象, 如果有直接获取,不会发送SQL 语句,否则才发送SQL
public void cache(){
Session session = SessionUtils.getCurrentSession();
session.beginTransaction();
Query query = null;
DataType dataType = null;
DataType dataType1 = null;
try {
// 获取要修改的对象
dataType = (DataType) session.get(DataType.class, new Long(1));
// session.evict(dataType);和session.clear();方法会清理缓存
dataType1 = (DataType) session.get(DataType.class, new Long(1));
System.out.println(dataType == dataType1);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
}
List() 查询出来的结果会被缓存起来,那么当 terator() 再查看的时候会先发送查询id 的SQL , 但是查询实体的SQL 不会发出,因为它首先回去一 级缓存中获取已经缓存的数据。
public void cache(){
Session session = SessionUtils.getCurrentSession();
session.beginTransaction();
Query query = null;
try {
query = session.createQuery("from DataType");
List list = query.list();
System.out.println(list);
// session.clear();
Iterator<DataType> it = query.iterate();
while(it.hasNext()){
System.out.println(it.next());
}
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
}
Iterator() 方法加载的所有的持久化类对象要进行 批处理修改的时候,每一个对象都要先缓存再修改, 因此在循环中需要释放一级缓存中的内存占用,避免 内存溢出。
public void cache(){
Session session = SessionUtils.getCurrentSession();
session.beginTransaction();
Query query = null;
try {
query = session.createQuery("from DataType");
Iterator<DataType> it = query.iterate();
while(it.hasNext()){
DataType dataType = it.next();
dataType.setVip('K');
session.flush();
session.clear();
}
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
}
面试题
面试题1: 不同的session是否会共享缓存数据?
不会。
User1 u1 = Session1.get(User.class,1); 把u1对象放入session1的缓存
Session2.update(u1); 把u1放入session2的缓存
U1.setName(‘new Name’);
如果生成2条update sql, 说明不同的session使用不同的缓存区,不能共享。
面试题2: list与iterator查询的区别?
- list()
一次把所有的记录都查询出来,
会放入缓存,但不会从缓存中获取数据
- Iterator
N+1查询; N表示所有的记录总数
即会先发送一条语句查询所有记录的主键(1),
再根据每一个主键再去数据库查询(N)!
会放入缓存,也会从缓存中取数据!