1.回顾Java对象在JVM中的生命周期
* java集合(List,Set,Map)一个重要的特性是:集合中存放的java对象的引用。当向集合添加一个对象时,其实是把对象的引用添加到集合中。
2.session概述
* Session 接口是 Hibernate 向应用程序提供的操纵对数据库的最主要的接口, 它提供了基本的保存, 更新, 删除和加载Java 对象的方法
* 在 Session 接口的实现中包含一系列的 Java 集合, 这些 Java 集合构成了 Session 缓存. 只要 Session 实例没有结束生命周期, 存放在它缓存中的对象也不会结束生命周期
* 当session的save()方法持久化一个对象时,该对象被载入缓存,以后即使程序中不再引用该对象,只要缓存不清空,该对象仍然处于生命周期中。当试图load()对象时,会判断缓存中是否存在该对象,有则返回。没有在查询数据库
3.清理session的缓存
* Session 具有一个缓存, 位于缓存中的对象称为持久化对象, 它和数据库中的相关记录对应. Session 能够在某些时间点, 按照缓存中对象的变化来执行相关的 SQL 语句, 来同步更新数据库, 这一过程被称为清理缓存
* 当应用程序调用 Transaction 的 commit()方法的时, 该方法先清理缓存(session.flush()),然后在向数据库提交事务(tx.commit())
4. 清理session的缓存 测试flush方法的使用
* 清理缓存,刷新session的一级缓存中数据到数据库中,让缓存中的数据跟数据库同步 方向缓存--->数据库 缓存中的数据不丢失
* session.flush()执行时 会产生insert语句 此时已经在数据库当中 但是数据库还没有确认 tx.commit(); 数据库确认
@Test
public void testFlushClear(){
Session session=sf.openSession();
Transaction tx=session.beginTransaction();
Customer c4=(Customer)session.get(Customer.class, 4); //select
session.flush();
Customer c5=(Customer)session.get(Customer.class, 4); //不会产生select语句
session.clear();
Customer c6=(Customer)session.get(Customer.class, 4); //会产生select语句
tx.commit(); //数据库确认插入的数据
session.close();
}
* session.clear();清除缓存 由于清除了缓存 所以再查询的时候 会产生select语句
5.清理session缓存 测试快照
public void testSessionUpdateCache(){
Session session=sessionFacoty.openSession();
Transaction tx=session.beginTransaction();
Customer c=(Customer)session.get(Customer.class, 1);
//修改对象属性的值
c.setName("张飞");
//该行代码加和不加没有影响
//session.update(c);
tx.commit();
session.close();
}
* 当session加载了customer对象后,会为customer对象的值类型的属性复制一份快照。当清理缓存时,通过比较对象的当前属性和快照,来判断对象的那些属性发生了变化
6.清理session缓存 测试refresh方法的使用
@Test
public void tesRefresh(){
Session session=sf.openSession();
Transaction tx=session.beginTransaction();
Customer c4=(Customer)session.get(Customer.class, 4); //select
c4.setName("黄忠");
session.refresh(c4);
tx.commit(); //数据库确认插入的数据
session.close();
}
* 刷新数据库中的数据和缓存中的同步,方法向从数据库----> 缓存,产生select语句 所以会产生两条select语句
7.清理session的缓存 方法总结
* flush: 进行清理缓存(此时缓存中的数据并不丢失)的操作,让缓存和数据库同步 执行一些列sql语句,但不提交事务,;
* commit:先调用flush() 方法,然后提交事务. 则意味着提交事务意味着对数据库操作永久保存下来。
* refresh:刷新,让session和数据库同步,执行查询,把数据库的最新信息显示出来,更新本地缓存的对象状态
* clear:清空缓存,等价于list.removeAll(); 缓存就是一系列的集合
8.设置缓存的清理模式
* session.setFlushMode(FlushMode.NEVER); tx.commit(); 不会产生insert语句 session.flush();会产生insert语句
* 批量插入时,一定数量是必须要清理清除缓存,不然会内存溢出
9.临时对象(transient)
* 在使用代理主键的情况下, OID 通常为 null
* 不处于 Session 的缓存中
* 在数据库中没有对应的记录
10.删除对象(Removed)
* OID 不为 null
从一个 Session实例的缓存中删除
Session 已经计划将其从数据库删除, Session 在清理缓存时, 会执行 SQL delete 语句, 删除数据库中的对应记录
一般情况下, 应用程序不该再使用被删除的对象
11.持久化对象(也叫”托管”)(Persist)
* OID 不为 null
位于 Session 缓存中
持久化对象和数据库中的相关记录对应
Session 在清理缓存时, 会根据持久化对象的属性变化, 来同步更新数据库
在同一个 Session 实例的缓存中, 数据库表中的每条记录只对应唯一的持久化对象
12.游离对象(也叫”脱管”)(Detached)
* OID 不为 null
不再处于 Session 的缓存中
一般情况需下, 游离对象是由持久化对象转变过来的, 因此在数据库中可能还存在与它对应的记录
* 当session的缓存中保存了大量的持久化对象,会消耗许多内存空间,为了提高性能,为了提高性能,可以考虑使用evict方法,从缓从中删除一些持久化对象