第六章 JDOHelper
上图列出了JDOHelper最常用的方法。详细的API信息请参考类的Javadoc文档
应用程序使用JDOHelper进行三类操作:能持久化操作,生存期操作和创建PersistenceManagerFactory
。我们逐一研究。
6.1 能持久化操作
前两个操作makeDirty和getObjectId我们已经见过。假设一个能持久化对象和字段名被修改,
makeDirty 方法会告诉JDO字段值已经改变,将新值写到数据存储中去。通常JDO自动跟踪字段的修改,你使
用这个方法的唯一机会是你想赋新值给数组索引时。
getObjectId 方法返回JDO标志对象,这个方法要求以持久类实例作为参数。如果该实例的类不是持久的
,那么这个方法返回null
顾名思义,getPersistenceManager以能持久类作为参数,得到管理这个持久类的PersistenceManager
。如果参数实例是非持久的,返回null
6.2 生存期操作
JDO能识别能持久类的几种生存期状态。在JDO规范规定实例的状态转换遵守严格的规则。状态转换可以被
显式的行为触发,例如调用PersistenceManager的deletePersistent 方法删除某个持久对象,也能被隐
式行为触发,例如读取某个持久字段。
下面列出能持久类实例的生存期状态。除非特别声明,每种状态都能被所有JDO实现品支持。别在意你能不
能记住状态和转换行为,实践中你很少会考虑到他们。
1)Transient:通过自定义构造函数创建而没有和持久框架关联的对象称为暂时性对象。如果没有JDO,那
么对象就是暂时性对象。
2)Persistent-new:对象调用PersistenceManager.makePersistent方法使自身持久而又没有插入到
数据存储中的状态称为“新持久”状态。当对象转换为这个状态的时候,会得到一个JDO标识。
在事务提交时,新持久状态对象的信息会插入到数据存储。事务回滚时,一个新持久实例回复暂时性状态
。数据存储不起作用。如果事务的RestoreValues属性赋值为true,实例的持久事务化字段会回复事务刚开
始时的值。
3)Persistent-new-deleted:在当前事务,对象刚由PersistenceManager.makePersistent创建或由
PersistenceManager.deletePersistent删除会进入这个状态。此时你只能访问对象的主键字段。如果试
图访问其他持久字段,会返回JDOUserException
在事务提交时,处于persistent-new-deleted 状态的对象会转为暂时状态。其持久性字段的值会被JAVA
的默认值替代。事务回滚是,处于persistent-new-deleted 状态的对象也会转为暂时状态,在这种情况下
,如果事务的RestoreValues 属性设为true,它持久事务性的字段值会回复到事务刚开始时那样。否则不改
变。
4)Persistent-clean:在当前事务中持久性字段未作出改变的对象所表现的状态称为
Persistent-clean
5)Persistent-dirty:当前事务中持久性字段值改变的对象状态称为Persistent-dirty。在事务提交
后,数据存储会更新反映对象的持久性状态。
6)Persistent-deleted:如果某个持久化对象是PersistenceManager.deletePersistent对象的参
数,它就变为PersistenceManager.deletePersistent的状态。对象处于这个状态时,你只能访问它的主
键字段,访问其他字段会导致JDOUserException。
事务提交时处于persistent-deleted状态的对象会转为暂时的。对象的存储记录已被清除。
7)Hollow:未从数据存储读取值的持久对象处于Hollow状态,只要实例进入Hollow状态,它持久性字段
的值会被代之以JAVA默认值。当你第一次访问这些字段的时候,这些字段会从数据存储重新装载,如果有必要
,可以延迟读取信息的时间,这称为懒惰装载。
JDO实现品对处于Hollow状态实例的跟踪是不牢固的,如果你的应用程序没有保留对它们的引用,那么它们
会被垃圾回收。
8)Persistent-nontransactional:处于Persistent-nontransactional状态的对象表现为持久数据
在数据存储里,但不保证是最新的值。一个允许访问数据旧值的状态好像是没用的,但如果使用得当,你会发
现当你引入程序的过时数据时,处于此状态的对象能提供更好的性能。
这个状态是JDO的可选特性,有可能不被许多JDO实现品支持。这也是目前为止最复杂的生存期,它由事务
的NontransactionalRead, NontransactionalWrite, RetainValues, 和Optimistic properties等
管理。当下节介绍PersistenceManagerFactory 属性的时候,我们会讨论这些属性。
在事务之外,读写处于Persistent-nontransactional状态的持久字段不会导致状态改变。当开始数据事
务时,你对这个实例的持久字段所作的任何修改都会被忽略。而当你在事务之内读
Persistent-nontransactional状态对象的持久字段则会转换为persistent-clean状态,而写则会转化为
persistent-dirty状态。在最优事务内,读不会转化状态,写则会转化为persistent-dirty状态。
9)Transient-clean:Transient-clean和transient-dirty两种状态可以归为
transient-transactional类别,处于Transient-transactional状态的对象并不持久化,不过它们的字段
可以作为事务的边界.意味着当事务回滚的时候它们可以回复之前的值.通过把暂时性实例作为参数,调用
PersistenceManager的makeTransactional 方法, 你可以使它变成Transient-transactional.一些
JDO厂商不支持transient-transactional 状态,它是JDO规范的可选特性.
10)Transient-dirty:处于Transient-transactional 状态的实例在当前事务被修改则进入
transient-dirty
状态,在事务完成之后,处于此状态的对象会变成transient-clean.如果事务回滚和它的RestoreValues属
性设为true,那么持久化和事务字段会回复事务开始之前的值.
下图描述了持久化对象的状态转化.箭头表示从一种状态转换为另一种状态.箭头下的文字显示了触发状态转
换的事件.用紫色表示的方法名是事务接口里的方法,用红色表示的方法名是PersistenceManager 接口的方
法.等会我们会介绍这些接口.
在复习完JDO生存期状态之后,JDOHelper的生存期操作--isDirty, isTransactional,
isPersistent, isNew, isDeleted --的目的就完全清楚了.每个都告诉你能持久实例是否有如名字显示的
那种属性,这些属性由实例的生存期状态决定.事实上,根据下面的表格,你可以根据这些属性计算出实例的状态
.然而再次声明,实践中很少需要担心你能持久化类的生存期状态.
6.3. PersistenceManagerFactory 构造函数
你可以厂商无关的风格调用JDOHelper的getPersistenceManagerFactory 方法来获得
PersistenceManagerFactory PersistenceManagerFactory 对象,这个方法需要一个参数:一个
java.util.Properties类的实例.这个实例的作用是设定PersistenceManagerFactory ,每次调用这个方
法,厂商都可以构造一个新的PersistenceManagerFactory 对象,或者返回连接池中匹配所提供属性的
PersistenceManagerFactory 对象.可供使用的配置选项和相关属性名称会在下章讨论.