HIbernate有两级缓存:Session中为一级(内置),SessionFactory中为二级缓存(外置)。
1.缓存中对象的生命周期:
当对象成为持久态,即被放入一级缓存,生命直到session关闭。相关操作:save、update、get/load、Query、Criteria
2.缓存的清空:
一级缓存中的数据,会在某些时间点,同步到数据库。发生此动作时session执行flush操作。
1)提交事务:
transaction.commit();
2)手动刷出:
(1)
session.flush;
(2)
session.close();
session
首先
flush
,然后
close
。
3)被动刷出:
当调用查询语句时,一级缓存数据已经发生了变化,session会首先刷出缓存同步到数据库,然后返回查询结果。
3.flush、clear、evict三个方法的使用:
1)证明一级缓存的存在:
(1)JavaBean重写toString()方法:
(2)查询:
@Test
public void test() {
Session session = UtilGetSession.openSession();
Transaction transaction = session.beginTransaction();
PojoUser user1 = (PojoUser) session.get(PojoUser.class, 3);
System.out.println("第一次查询:"+user1);
//第二次的id和上一次查询的id相同,将直接从缓存获取
PojoUser user2 = (PojoUser) session.get(PojoUser.class, 3);
System.out.println("第二次查询:"+user2);
transaction.commit();
session.close();
}
2)flush方法,同步数据到数据库:
(1)原理:
(2)代码:
public void test() {
Session session = UtilGetSession.openSession();
Transaction transaction = session.beginTransaction();
// step3 get方法获得持久化对象,从数据库返回后放入缓存和快照各一份
PojoUser user = (PojoUser) session.get(PojoUser.class, 3);
System.out.println("第一次查询:"+user);
//step5 set方法使缓存中的数据发生了变化
user.setName("Amelie");
// step6 执行flush前先对比缓存和快照中的数据是否相同,不同则先执行update
session.flush();
transaction.commit();
session.close();
}
(3)结果:
3)clear方法,清空一级缓存:
(1)代码:
public void test() {
Session session = UtilGetSession.openSession();
Transaction transaction = session.beginTransaction();
PojoUser user1=(PojoUser)session.get(PojoUser.class, 3);
System.out.println(user1);
session.clear(); //清空缓存
//一级缓存中已经没有持久化对象了,重新生成
PojoUser user2=(PojoUser)session.get(PojoUser.class, 3);
System.out.println(user2);
transaction.commit();
session.close();
}
(2)结果:
4)evit方法,清除指定缓存对象:
public void test() {
Session session = UtilGetSession.openSession();
Transaction transaction = session.beginTransaction();
PojoUser user1=(PojoUser)session.get(PojoUser.class, 3);
System.out.println(user1);
session.evict(user1); //清空缓存中的指定持久化对象
//一级缓存中已经没有指定的持久化对象了,重新生成
PojoUser user2=(PojoUser)session.get(PojoUser.class, 3);
System.out.println(user2);
transaction.commit();
session.close();
}
4.快照:
在一级缓存中存放数据时,都会保存一个备份,即快照。执行flush操作时,会对比缓存数据是否和快照相同,否则执行update。
持久化对象因为快照的存在,会自动更新数据库;无需手动update。
5.refresh,刷新一级缓存:
重新从数据库加载数据,覆盖原一级缓存。
(1)代码:
public void test() {
Session session = UtilGetSession.openSession();
Transaction transaction = session.beginTransaction();
PojoUser user=(PojoUser)session.get(PojoUser.class, 3);
System.out.println(user);
user.setName("Michael Jackson"); //更新一级缓存
//从数据库读取数据,覆盖原一级缓存。导致上面的set操作无效
session.refresh(user);
System.out.println(user);
System.out.println(user);
transaction.commit();
session.close();
}
(2)结果:
6.flushmode,设置一级缓存刷出时间:
AUTO:介于COMMIT和ALWAYS。默认。
COMMIT:事务提交Transaction.commit()时进行刷出
ALWAYS:每次查询前都会刷出
MANUAL:必须手动调用Session.flush()才会刷出。当事务提交亦不会刷出;Query查询亦不刷出
刷出力度:Session.flush > Transaction.commit > Query查询
1)级别为manual:
Session.flush();
2)级别为commit:
Session.flush();
Transaction.commit;
3)级别为always:
Session.flush();
Transaction.commit;
Query查询操作;
刷出级别:MANUAL > COMMIT > AUTO > ALWAYS。
代码:
Session.setFlushMode(FlushMode.ALWAYS);
- end