Hibernate Session 中的缓存机制

Session接口是Hibernate向应用程序提供的操纵数据库的最主要的接口,它提供了基本的保存、更新、删除和查询方法。Session具有一个缓存,位于缓存中的对象处于持久化状态,它和数据库中的相关记录对应,Session能够在某些时间点,按照缓存中持久化对象的属性变化来同步更新数据库,这一过程被称为清理缓存。


处理持久化状态,对象还能处于游离状态和临时状态,Session的特定方法能使对象从一个状态转换到另一个状态。




一、Java对象在JVM中的生命周期
当应用程序通过new语句创建一个Java对象时,JVM会为这个对象分配一块内存空间,只要这个对象被引用变量引用,它就一直存在于内存中。如果这个对象不被任何引用变量引用,它就结束生命周期,此时JVM的垃圾回收器会在适当时候回收它占用的内存。


二、理解Session的缓存
如果希望一个Java对象一直处于生命周期中,就必须保证至少有一个变量引用它,或者在一个Java集合中存放了这个对象的引用。在Session接口的实现类SessionImpl中定义了一系列的Java集合,这些Java集合构成了Session的缓存。


Session缓存的三大作用:
1、 减少访问数据库的频率。从而提高数据访问的性能。
2、 保证缓存中的对象与数据库中的相关记录保持同步。位于缓存中的对象被称为持久化对象。当缓存中的对象的状态发生了变换,Session并不会立即执行相应的SQL于户,这使得Session能把几条相关的SQL语句合并为一条SQL语句,一边减少访问数据库的次数,从而提高应用程序的性能。
3、 当缓存中的持久化对象之间存在循环关联关系时,Session会保证不出现访问对象图的死循环,以及由于死循环引起的JVM栈溢出异常。
注:当Session加载了对象后,会为对象的值类型的属性赋值一份快照。当Session清理缓存时,通过比较对象的当前属性和它的快照,Session能够判断对象的哪些属性发生了变化。


Session在清理缓存时,按照以下顺序执行SQL语句。
l 按照应用程序调用session.save()方法的先后顺序,执行所有对实体进行插入的insert语句。
l 执行所有对实体进行更新的update语句。
l 执行所有对集合进行删除的delete语句。
l 执行所有对集合元素进行删除、更新或者插入的SQL语句。
l 执行所有对集合进行插入的insert语句。
l 按照应用程序调用session.delete()方法的先后顺序,执行所有对实体进行删除的delete语句。


在默认情况下,Session会在下面的时间点清理缓存。
l 当应用程序调用net.sf.hibernate.Transaction的commit()方法的时候,commit()方法先清理缓存,然后在向数据库提交事务。
l 当应用程序调用Session的find()或者iterate()时,如果缓存中持久化对象的属性发生了变化,就会先清理缓存,以保证查询结果能能反映持久化对象的最新状态。
l 当应用程序显式调用Session的flush()方法的时候。
Session进行清理缓存的例外情况是,如果对象使用native生成OID,那么当调用Session的save()保存该对象时,会立即执行向数据库插入实体的 insert语句。


注:Session的commit()和flush()方法的区别。flush方法进行清理缓存的操作,执行一系列的SQL语句,但不会提交事务;commit方法会先调用flush方法,然后提交事务。提交事务意味着对数据库所作的更新被永久保存下来。

AUTO时默认值,这也是优先考虑的清理模式,他会保证在整个事务中,数据保持一致。如果事务仅包含查询数据库的操作,而不会修改数据库的数据,也可以选COMMIT模式,这可以避免在执行Session的 查询方法时先清理缓存,以稍微提高应用程序的性能。
在多说情况下,应用程序不需要显式调用Session的flush方法,flush方法适用于以下场合。
A、插入、删除或更新某个持久化对象会引发数据库中的触发器。
B、 在应用程序中混合使用Hibernate API和JDBC API。
C、 JDBC驱动程序不健壮,导致Hibernate在自动清理缓存的模式下无法正常工作。


三、在Hibernate应用中Java对象的状态
对于需要持久化的Java对象,在它的生命周期中,可处于以下三个状态之一。
l 临时状态(transient):刚刚用new语句创建,还没有被持久化,不处于Session的缓存中。处于临时状态的Java对象被称为临时对象。
l 持久化状态(persistent):已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久化对象。
l 游离状态(detached):已经被持久化,但不在处于Session的缓存中。处于游离状态的Java对象被称为游离对象。


注:持久化类与持久化对象是不同的概念。持久化类的实例可以处于临时状态、持久化状态和游离状态,其中处于持久化状态的实例被称为持久化对象。


1、临时对象的特征
不处于Session的缓存中(不被任何一个Session实例关联);在数据库中没有对应的记录。
以下情况下,Java对象进入临时状态:
A、当new语句刚刚创建对象;
B、 Session的delete()方法能使一个持久化对象或游离对象转变为临时对象。


2、持久化对象的特征
位于一个Session实例的缓存中;持久化对象和数据库中的相应记录对应;Session在清理缓存时,会根据持久化对象的属性变化,来同步更新数据库。
Session的许多方法能触发Java对象转变为持久化对象:
A、save把临时转为持久化状态;
B、 load或get返回的对象总处于持久化状态;
C、 find返回的List集合中存放的都是持久化对象;
D、update、saveOrUpdate和lock方法使游离对象转变为持久化对象;
E、 当一个持久化对象关联一个临时对象,在允许级联保存的情况下,清理缓存时会把临时对象转化为持久化对象。


3、游离对象的特征
不再位于Session的缓存中;游离对象是由持久化对象转变过来的,因此再数据库中可能存在与它对应的记录(前提是没有其他程序删除这条记录)。
Session的以下方法使持久化对象转变为游离对象:
A、close方法,缓存被清理空,所有持久化对象都变为于哦里对象;
B、 evict方法能够从缓存中删除一个持久化对象。


四、Session的保存、更新、删除和查询方法
1、Session的save方法
使一个临时的对象转变为持久化对象。
Session的save方法完成以下操作:
A、把对象加入到缓存中,使它变为持久化对象。
B、 选用映射文件指定的标识符生成器为持久化对象分配唯一的OID。
C、 计划执行一个insert语句,把对象当前的属性值组装到insert语句中。
值得注意的是,save方法并不立即执行SQL insert语句。只有当Session清理缓存时,才会执行语句。


Session的save方法是用来持久化一个临时对象的。再应用中,不应该把持久化对象或游离对象传给save方法。


2、Session的update方法
使一个游离对象转变为持久化对象。
Session的update方法完成以下操作:
A、把对象重新加入到Session的缓存中,使它变为持久化对象。
B、 计划执行一个update语句。(不立即执行,清楚缓存执行)


3、Session的saveOrUpdate方法
同时包含 了save和update方法的功能,如果传入的参数是临时对象,就调用save方法;如果传入的参数是游离对象,就调用update方法;如果传入的参数是持久化对象,那就直接返回。


4、Session的load和get方法
根据给定的OID从数据库中加载一个持久化对象,这两个方法的区别在于:当数据库中不存在与OID对应的记录时,load方法抛出异常,而get方法返回null。


5、Session的delete方法
在数据库中删除与Java对象对应的记录。如果传入的参数时持久化对象,Session就计划执行一个delete语句。如果传入的参数时游离对象,先是的游离对象被Session关联,使它变为持久化对象,然活计划执行一个delete语句。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值