前言
在hibernate的学习过程中,学到了缓存,对于我这个文科生来说,对于缓存自然是不懂不理解的,找来一本书,仔细地看了一下,算是理解了一些,回来总结总结。
缓存
缓存在计算机中是非常通用,它介于应用程序和永久性数据存储源(如磁盘和数据库)之间。其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的复制,只有在某些特定时刻按照缓存中的数据来同步更新数据存储源。应用程序与缓存之间是频繁写、频繁读,缓存与永久性数据存储源偶尔写、偶尔读。
缓存的物理介质是内存,而永久性数据存储源的物理介质通常是硬盘或磁盘,应用程序读写内存的速度比读写硬盘的速度快。但是如果缓存存放的数据量非常大,也会用硬盘作为缓存的物理介质。
如:我们用word编辑的时候,会自动保存草稿在缓存中,如果我们将这些文档保存起来,word就会照缓存中的数据来同步更新硬盘中的文本文件,这时便是永久性数据。
Hibernate缓存
Hibernate提供了两级缓存,第一级缓存是Session的缓存,第二级缓存由SessionFactory管理。
第一级缓存
由于Session对象的生命周期通常对应一个数据库事务或者一个应用事务,因此它的缓存是事务范围的缓存,在第一级缓存中,持久化类的每个实例都具有唯一的OID(对象标识符。第一级缓存是必需的,所以它是不可卸载的。
Hibernate的第一级缓存中,Session提供save(),update(),saveOrUpdate(),load()或get()方法,以及调用Query查询接口的list(),iterate()或filter()方法。如果Session的缓存中还不存在相应的对象,Hibernate就会把这个对象加入到第一级缓存中。当清理缓存是,Hibernate会根据缓存中对象的状态变化来同步更新数据库,Hibernate提供了evict(Object o)和clear()两个方法清理缓存。
栗子:
public void testCache7() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
for (int i=0; i<100; i++) {
Student student = new Student();
student.setName("张三" + i);
session.save(student);
//每20条更新一次
if (i % 20 == 0) {
session.flush();
//清除缓存的内容
session.clear();
}
}
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
第二级缓存
Hibernate第二级缓存是一个可插拔的缓存插件,由SessionFactory负责管理。SessionFactory对象的生命周期和应用程序的整个进程对应,因此第二级缓存是进程范围或集群范围的缓存。存放的是对象的散装数据。第二级缓存可能会出现并发问题,因此需要采用适当的并发策略,这些策略也会为被缓存的数据提供了事务隔离级别。
Hibernate的第二级缓存可以选用EHCache,OpenSymphony OSCache,SwarmCache,JBossCache缓存插件。
栗子:
public void testCache1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Student student = (Student)session.load(Student.class, 1);
System.out.println("student.name=" + student.getName());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Student student = (Student)session.load(Student.class, 1);
//不会发出查询语句,因为配置二级缓存,session可以共享二级缓存中的数据
//二级缓存是进程级的缓存
System.out.println("student.name=" + student.getName());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
总结
算是把缓存理解了一遍,对于Hibernate的缓存还是需要多实践才行。