一. 理解Session的缓存
当Session的save()方法持久化一个Customer对象事,Customer对象被加入到Session的缓存中,以后即使应用程序中的引用变量不再引用Customer对象,只要Session的缓存还没有被清空,Customer对象仍然处于生命周期中。
当Session的load()方法视图从数据库中加载一个Customer对象时,Session先判断缓存中是否已经存在这个Customer对象,如果存在,就是不需要再到数据库中检索。
tx = session.beginTransaction();
Customer c1 = new Customer();
c1.setName("zhangsan");
//Customer对象被持久化,并且加入到Session的缓存中
session.save(c1);
int id = c1.getId();
//c1变量不再引用Customer对象
c1 = null;
//从缓存中读取Customer对象,使c2变量引用Customer对象
Customer c2 = (Customer)session.load(Customer.class, id);
tx.commit();
//关闭Session,清空缓存
session.close();
//访问Customer对象
System.out.println(c2.getName());
//c2变量不再引用Customer对象
c2 = null;
二. Session缓存的作用
(1)减少访问数据库的频率。应用程序从内存中读取持久化对象的速度显然比到数据库中查询数据库的速度快多了,因此Session的缓存可以提高数据库访问的性能。
(2)保证缓存中的对象与数据库中的相关记录保持同步。当缓存中持久化对象的状态发生了变化,Session并不会立即执行相关的SQL语句,这使得Session能够把几条相关的SQL语句合并为一条SQL语句,以便减少访问数据库的次数,从而提高应用程序的性能。
三. Session清理缓存
清理缓存是指按照缓存中对象的状态的变化来同步更新数据库
一下程序代码对Customer的name属性修改了两次:
tx = session.beginTransaction();
Customer cus = (Customer)session.load(Customer.class, 2);
cus.setName("lisi");
cus.setName("wangwu");
tx.commit();
当Session清理缓存时,只需执行一条update语句:update customer set name='wangwu' where id = 2;
注:get和load方法都会在对象属性修改后update到数据库。
Session会在下面的时间点清理缓存:
- 当应用程序调用org.hibernate.Transaction的commit()方法的时候,commit()方法先清理缓存,然后再向数据库提交事务。
- 当应用程序显示调用Session的flush()方法的时候。
四. Hibernate的两级缓存结构
Session级别的缓存又叫做一级缓存;SessionFactory级别的缓存叫做二级缓存。
(1)Hibernate提供了两级缓存,第一级缓存是Session的缓存。由于Session对象的生命周期通常对应一个数据库事务或者一个应用事务,因此它的缓存时事务范围的缓存。第一级缓存是必须的,不允许而且也不能被卸除。在第一级缓存中,持久化类的每个实例都具有唯一的OID。
(2)第二级缓存是一个可插拔的缓存插件,它由SessionFactory负责管理。由于SessionFactory对象的生命周期和应用程序的整个进程对应,因此第二级缓存是进程范围的缓存。这个缓存中存放的是对象的散装数据。第二级缓存是可选的,可以在每个类或每个集合的粒度上配置第二级缓存。
五. 在Hibernate应用中java对象的状态
临时状态(transient):刚刚用new语句创建,还没有被持久化,不处于Session的缓存中。处于临时状态的Java对象被称为临时对象。
持久化状态(persistent):已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久化对象。
游离状态(detached):已经被持久化,但不再处于Session的缓存中。处于游离状态的Java对象称为游离对象。
游离对象与临时对象不同的是游离对象中已经填充了OID。