基于java的对象持久性设计方案浅议
2014-07-16黄锡刚
黄锡刚
摘要:该文讨论的是在传统中间件环境下,在数据库多层访问模型的基础上,利用对象/关系映射如何实现对象持久性设计方案。
关键词:持久性对象;关系数据库;三层模型;对象标识
中图分类号:TP393 文献标识码:A 文章编号:1009-3044(2014)14-3285-03
持久对象需解决内存中瞬时对象与其他存储设备上持久对象的数据格式转换问题。主要的存储设备有以下的三种:
1)文件系统。可以通过串行化对象来将对象保存在一个文件中。当应用程序设计中要求使用文件系统作为持久性基础设施来实现应用程序中相关对象的持久性时,我们可以自定义一个文本文件的格式,将对象的状态存储在该文件中。
2)对象数据库。这是保证对象持久性的最合理的做法。但大多数公司还只是刚开始研究对象数据库,所以还不是主流的存储介质。
3)关系数据库。目前大多数先进的应用程序都使用面向对象的数据结构。但在企业级的应用中大部分的数据库系统仍然是关系型数据库。虽然面向对象的数据结构对很多应用必不可少,但我们仍然要考虑很多原有系统的需要,所以关系数据库的应用还是主流。
持久性一般可以分成两类:空间上的持久性和时间上的持久性。空间上的持久性是在网络中传递对象的状态,例如:远程方法调用RMI(Remote Method Invocation, RMI是java分布式对象(EJB)的通信基础设施)将对象状态串行化后,通过socket传输串行化结果。时间上的持久性中,轻量型持久对象通常保存在本地文件系统中;重量型持久性对象通常采用:O/R映射(关系/对象映射)+RDB(关系数据库)来解决。
最简单的持久性实现方案是在应用程序启动时从文件装入相关对象的状态,在程序结束时将相关对象的状态存到该文件中。但当我们要采用可扩展性更好的持久性方案时,譬如实现对象瞬时(transient)状态的更新与其持久性是同步的的时候,O/R+RDB的解决办法就显得非常实用了。
1 关系数据库的应用
企业级的应用大多数都采用三层模型来使用中间件访问数据。典型的三层模型由上到下分别是:表示层、业务逻辑层、数据层。三层结构将业务逻辑抽取出来作为一个独立的中间层。业务逻辑层是对企业所有业务逻辑的一种抽象,对上:为表示层提供了更高级的API;对下:封装了整个数据层。企业级的应用还可以是以三层结构为基础的扩展,例如:在业务逻辑层与数据层之间引入一层“持久对象层”,持久对象层可以实现对象/关系映射,数据类型转换等功能。
数据库是企业级应用的基础设施。在开发数据库应用系统时,引入对象-关系映射中间件是提高开发效率、提升软件可维护、扩展性的需要。成熟的对象-关系映射中间件产品,可以把内存中的对象持久化到数据库中,但前提是我们必须设计好自己的持久性对象、合理的对象持久性方案。持久性保存数据到一个数据库需要注意的是尽量的保持对象持久性的高度透明化。理由有以下4点:1) 企业应用需要实现持久性对象,例如:客户、供应商、货品、订单等资料都需要持久性的保存到数据库中。2) 代表业务逻辑的对象可独立于使用它们的程序而存在。3) 多个应用程序可能需要工作在同一个对象上。4) 当对象与另一个对象交流时,不必了解该对象在内存还是在外存。
2 O/R映射基本规则
对象范式与关系范式之间存在阻抗不匹配问题,利用已有的O/R映射模式可帮助设计人员避免实现对象持久性的陷入误区。基本的映射规则有以下的三点:
1)将属性影射为列。并不是所有属性都是持久性的。通常,依赖属性都不是持久性的。例如:记帐凭证中的借、贷合计。
2)将类映射为表。形式可以是多个类映射到单张表、单张表映射到多张表。多个类映射到同一张表这种情况是由于对象范式含有数据与操作,关系范式仅有数据,所有O/R映射丢失操作后,某些数据可能更适合合并。一个类映射到多张表,这种情况一般是由于要考虑程序效率才这样做。在某些情况下划分多张表会提高性能,但如果执行涉及连接的操作则通常反而降低性能。
3)类间关系(继承、聚集、关联)的映射。继承关系的映射,一般有三种形式:①整个类层次使用一张表,类层次中所有类的所有属性均存放在该表中。②每个叶结点类使用一张表。③每个类使用一张表,该表只保存OID(对象标识)以及对应类自己的属性(不含所继承的属性)。关联与聚类关系的映射从关系范式的角度来看,区别仅在于耦合程度不同而已。聚类耦合程度高:通常对“整体”操作都伴随着对“部分”。关联则不存在这么高的相关度。
3 对象持久性的设计方案
为了将设计阶段的工作过程清晰的表达出来,该文简单的设计一个餐馆订餐小系统来说明整个设计过程。
第一步:标志那些数据需要持久性。
对象标识(OID)唯一标识关联对象/关系,在关系范式里该标识称为关键码(key),在对象范式里就是作为持久对象标识。OID的实现既可以是一个轻量级对象,也可以是整数、字符串等。OID设计的基本要求是唯一性和不变性。OID有3种层次的唯一性:1。在同一个类中具有唯一性。2。在同一个类层次中具有唯一性。3,在所有对象中均有唯一性。唯一性范围越大,则通常的开销也越大。例如:需要更长的计算机时间以获取OID,需要更多的存储空间以存放OID。OID的不变性是我们容易忽略的一个重要特征,因为任何业务逻辑含义都会发生变化,从而,任何对象标识不应含有任何业务逻辑含义。
在UML中类是作为指派持久性的基本单位。因为并不是每一个类都需要持久性,所以在设计过程中用带标签的值来标志持久性,可以采用(名字、值)简写的方式来表示,名字为类名,值分别记为Persistent(持久的)和transitory(暂时的),其中默认情况下是transitory(如下图所示)。这一步的设计我们要注意的是两个持久类之间的关联也是持久的。
第二步:设计合适的数据库模式。
在数据库设计阶段,简单的设计4张表:Table(桌子) 、Customer(顾客)、Walkin(无预订散客)、Reservation(预约)。每一张表添加显式的对象标识(OID),实现链接时用这些对象标识作为外码(FK)。由于本文所设计的Booking类是一个抽象类,可以简单地将其具体之类映射为表。餐馆订餐小系统数据库模式设计结果为:
第三步:解决对象与关系的同步问题
这时要解决的问题是:哪一个对象的职责应包含往数据库存放或从数据库装入对象的功能?因为指派为已有的类会导致聚合性降低,所以引入一个新的类专门执行该职责。为每一持久类定义一个映射类(Mapper)。在设计模型中引入对象标识,从而在领域模型之外亦可实现持久性。为每一持久性类定义子类,在子类中添加对象标识。Mapper类处理具有持久性的子类。
第四步:持久性体系结构设计
Persistent子类和Mapper类依赖于它们所支持的类。它们应出现在业务逻辑层,但Restaurant类依赖于 Mapper类。将业务逻辑层划分为两个子包。从而尽量避免了子程序包Persistency的变化对子程序包Domain带来的影响。持久性体系结构图如图4。
4 结束语
实现重量型持久性对象本文推荐的解决方案是O/R+RDB。持久性对象的设计的过程为:1)标识哪些数据需要持久性;2)设计一个合适的数据库模式;3)解决对象与关系的同步问题,最后总结自己的持久性体系结构。该文所描述的持久性对象的设计过程可以为解决同类问题的提供参考。
参考文献:
[1] 宋波,刘杰,杜庆东.UML面向对象技术与实践[M].北京:科学出版社,2005.
[2] 理查德森. Java高级编程:Jdk5[M].沈文炎,译.北京:机械工业出版社,2006.
[3] 霍顿.Java2入门经典:JDK5[M].潘晓雷,译.北京:机械工业出版社,2006.endprint
摘要:该文讨论的是在传统中间件环境下,在数据库多层访问模型的基础上,利用对象/关系映射如何实现对象持久性设计方案。
关键词:持久性对象;关系数据库;三层模型;对象标识
中图分类号:TP393 文献标识码:A 文章编号:1009-3044(2014)14-3285-03
持久对象需解决内存中瞬时对象与其他存储设备上持久对象的数据格式转换问题。主要的存储设备有以下的三种:
1)文件系统。可以通过串行化对象来将对象保存在一个文件中。当应用程序设计中要求使用文件系统作为持久性基础设施来实现应用程序中相关对象的持久性时,我们可以自定义一个文本文件的格式,将对象的状态存储在该文件中。
2)对象数据库。这是保证对象持久性的最合理的做法。但大多数公司还只是刚开始研究对象数据库,所以还不是主流的存储介质。
3)关系数据库。目前大多数先进的应用程序都使用面向对象的数据结构。但在企业级的应用中大部分的数据库系统仍然是关系型数据库。虽然面向对象的数据结构对很多应用必不可少,但我们仍然要考虑很多原有系统的需要,所以关系数据库的应用还是主流。
持久性一般可以分成两类:空间上的持久性和时间上的持久性。空间上的持久性是在网络中传递对象的状态,例如:远程方法调用RMI(Remote Method Invocation, RMI是java分布式对象(EJB)的通信基础设施)将对象状态串行化后,通过socket传输串行化结果。时间上的持久性中,轻量型持久对象通常保存在本地文件系统中;重量型持久性对象通常采用:O/R映射(关系/对象映射)+RDB(关系数据库)来解决。
最简单的持久性实现方案是在应用程序启动时从文件装入相关对象的状态,在程序结束时将相关对象的状态存到该文件中。但当我们要采用可扩展性更好的持久性方案时,譬如实现对象瞬时(transient)状态的更新与其持久性是同步的的时候,O/R+RDB的解决办法就显得非常实用了。
1 关系数据库的应用
企业级的应用大多数都采用三层模型来使用中间件访问数据。典型的三层模型由上到下分别是:表示层、业务逻辑层、数据层。三层结构将业务逻辑抽取出来作为一个独立的中间层。业务逻辑层是对企业所有业务逻辑的一种抽象,对上:为表示层提供了更高级的API;对下:封装了整个数据层。企业级的应用还可以是以三层结构为基础的扩展,例如:在业务逻辑层与数据层之间引入一层“持久对象层”,持久对象层可以实现对象/关系映射,数据类型转换等功能。
数据库是企业级应用的基础设施。在开发数据库应用系统时,引入对象-关系映射中间件是提高开发效率、提升软件可维护、扩展性的需要。成熟的对象-关系映射中间件产品,可以把内存中的对象持久化到数据库中,但前提是我们必须设计好自己的持久性对象、合理的对象持久性方案。持久性保存数据到一个数据库需要注意的是尽量的保持对象持久性的高度透明化。理由有以下4点:1) 企业应用需要实现持久性对象,例如:客户、供应商、货品、订单等资料都需要持久性的保存到数据库中。2) 代表业务逻辑的对象可独立于使用它们的程序而存在。3) 多个应用程序可能需要工作在同一个对象上。4) 当对象与另一个对象交流时,不必了解该对象在内存还是在外存。
2 O/R映射基本规则
对象范式与关系范式之间存在阻抗不匹配问题,利用已有的O/R映射模式可帮助设计人员避免实现对象持久性的陷入误区。基本的映射规则有以下的三点:
1)将属性影射为列。并不是所有属性都是持久性的。通常,依赖属性都不是持久性的。例如:记帐凭证中的借、贷合计。
2)将类映射为表。形式可以是多个类映射到单张表、单张表映射到多张表。多个类映射到同一张表这种情况是由于对象范式含有数据与操作,关系范式仅有数据,所有O/R映射丢失操作后,某些数据可能更适合合并。一个类映射到多张表,这种情况一般是由于要考虑程序效率才这样做。在某些情况下划分多张表会提高性能,但如果执行涉及连接的操作则通常反而降低性能。
3)类间关系(继承、聚集、关联)的映射。继承关系的映射,一般有三种形式:①整个类层次使用一张表,类层次中所有类的所有属性均存放在该表中。②每个叶结点类使用一张表。③每个类使用一张表,该表只保存OID(对象标识)以及对应类自己的属性(不含所继承的属性)。关联与聚类关系的映射从关系范式的角度来看,区别仅在于耦合程度不同而已。聚类耦合程度高:通常对“整体”操作都伴随着对“部分”。关联则不存在这么高的相关度。
3 对象持久性的设计方案
为了将设计阶段的工作过程清晰的表达出来,该文简单的设计一个餐馆订餐小系统来说明整个设计过程。
第一步:标志那些数据需要持久性。
对象标识(OID)唯一标识关联对象/关系,在关系范式里该标识称为关键码(key),在对象范式里就是作为持久对象标识。OID的实现既可以是一个轻量级对象,也可以是整数、字符串等。OID设计的基本要求是唯一性和不变性。OID有3种层次的唯一性:1。在同一个类中具有唯一性。2。在同一个类层次中具有唯一性。3,在所有对象中均有唯一性。唯一性范围越大,则通常的开销也越大。例如:需要更长的计算机时间以获取OID,需要更多的存储空间以存放OID。OID的不变性是我们容易忽略的一个重要特征,因为任何业务逻辑含义都会发生变化,从而,任何对象标识不应含有任何业务逻辑含义。
在UML中类是作为指派持久性的基本单位。因为并不是每一个类都需要持久性,所以在设计过程中用带标签的值来标志持久性,可以采用(名字、值)简写的方式来表示,名字为类名,值分别记为Persistent(持久的)和transitory(暂时的),其中默认情况下是transitory(如下图所示)。这一步的设计我们要注意的是两个持久类之间的关联也是持久的。
第二步:设计合适的数据库模式。
在数据库设计阶段,简单的设计4张表:Table(桌子) 、Customer(顾客)、Walkin(无预订散客)、Reservation(预约)。每一张表添加显式的对象标识(OID),实现链接时用这些对象标识作为外码(FK)。由于本文所设计的Booking类是一个抽象类,可以简单地将其具体之类映射为表。餐馆订餐小系统数据库模式设计结果为:
第三步:解决对象与关系的同步问题
这时要解决的问题是:哪一个对象的职责应包含往数据库存放或从数据库装入对象的功能?因为指派为已有的类会导致聚合性降低,所以引入一个新的类专门执行该职责。为每一持久类定义一个映射类(Mapper)。在设计模型中引入对象标识,从而在领域模型之外亦可实现持久性。为每一持久性类定义子类,在子类中添加对象标识。Mapper类处理具有持久性的子类。
第四步:持久性体系结构设计
Persistent子类和Mapper类依赖于它们所支持的类。它们应出现在业务逻辑层,但Restaurant类依赖于 Mapper类。将业务逻辑层划分为两个子包。从而尽量避免了子程序包Persistency的变化对子程序包Domain带来的影响。持久性体系结构图如图4。
4 结束语
实现重量型持久性对象本文推荐的解决方案是O/R+RDB。持久性对象的设计的过程为:1)标识哪些数据需要持久性;2)设计一个合适的数据库模式;3)解决对象与关系的同步问题,最后总结自己的持久性体系结构。该文所描述的持久性对象的设计过程可以为解决同类问题的提供参考。
参考文献:
[1] 宋波,刘杰,杜庆东.UML面向对象技术与实践[M].北京:科学出版社,2005.
[2] 理查德森. Java高级编程:Jdk5[M].沈文炎,译.北京:机械工业出版社,2006.
[3] 霍顿.Java2入门经典:JDK5[M].潘晓雷,译.北京:机械工业出版社,2006.endprint
摘要:该文讨论的是在传统中间件环境下,在数据库多层访问模型的基础上,利用对象/关系映射如何实现对象持久性设计方案。
关键词:持久性对象;关系数据库;三层模型;对象标识
中图分类号:TP393 文献标识码:A 文章编号:1009-3044(2014)14-3285-03
持久对象需解决内存中瞬时对象与其他存储设备上持久对象的数据格式转换问题。主要的存储设备有以下的三种:
1)文件系统。可以通过串行化对象来将对象保存在一个文件中。当应用程序设计中要求使用文件系统作为持久性基础设施来实现应用程序中相关对象的持久性时,我们可以自定义一个文本文件的格式,将对象的状态存储在该文件中。
2)对象数据库。这是保证对象持久性的最合理的做法。但大多数公司还只是刚开始研究对象数据库,所以还不是主流的存储介质。
3)关系数据库。目前大多数先进的应用程序都使用面向对象的数据结构。但在企业级的应用中大部分的数据库系统仍然是关系型数据库。虽然面向对象的数据结构对很多应用必不可少,但我们仍然要考虑很多原有系统的需要,所以关系数据库的应用还是主流。
持久性一般可以分成两类:空间上的持久性和时间上的持久性。空间上的持久性是在网络中传递对象的状态,例如:远程方法调用RMI(Remote Method Invocation, RMI是java分布式对象(EJB)的通信基础设施)将对象状态串行化后,通过socket传输串行化结果。时间上的持久性中,轻量型持久对象通常保存在本地文件系统中;重量型持久性对象通常采用:O/R映射(关系/对象映射)+RDB(关系数据库)来解决。
最简单的持久性实现方案是在应用程序启动时从文件装入相关对象的状态,在程序结束时将相关对象的状态存到该文件中。但当我们要采用可扩展性更好的持久性方案时,譬如实现对象瞬时(transient)状态的更新与其持久性是同步的的时候,O/R+RDB的解决办法就显得非常实用了。
1 关系数据库的应用
企业级的应用大多数都采用三层模型来使用中间件访问数据。典型的三层模型由上到下分别是:表示层、业务逻辑层、数据层。三层结构将业务逻辑抽取出来作为一个独立的中间层。业务逻辑层是对企业所有业务逻辑的一种抽象,对上:为表示层提供了更高级的API;对下:封装了整个数据层。企业级的应用还可以是以三层结构为基础的扩展,例如:在业务逻辑层与数据层之间引入一层“持久对象层”,持久对象层可以实现对象/关系映射,数据类型转换等功能。
数据库是企业级应用的基础设施。在开发数据库应用系统时,引入对象-关系映射中间件是提高开发效率、提升软件可维护、扩展性的需要。成熟的对象-关系映射中间件产品,可以把内存中的对象持久化到数据库中,但前提是我们必须设计好自己的持久性对象、合理的对象持久性方案。持久性保存数据到一个数据库需要注意的是尽量的保持对象持久性的高度透明化。理由有以下4点:1) 企业应用需要实现持久性对象,例如:客户、供应商、货品、订单等资料都需要持久性的保存到数据库中。2) 代表业务逻辑的对象可独立于使用它们的程序而存在。3) 多个应用程序可能需要工作在同一个对象上。4) 当对象与另一个对象交流时,不必了解该对象在内存还是在外存。
2 O/R映射基本规则
对象范式与关系范式之间存在阻抗不匹配问题,利用已有的O/R映射模式可帮助设计人员避免实现对象持久性的陷入误区。基本的映射规则有以下的三点:
1)将属性影射为列。并不是所有属性都是持久性的。通常,依赖属性都不是持久性的。例如:记帐凭证中的借、贷合计。
2)将类映射为表。形式可以是多个类映射到单张表、单张表映射到多张表。多个类映射到同一张表这种情况是由于对象范式含有数据与操作,关系范式仅有数据,所有O/R映射丢失操作后,某些数据可能更适合合并。一个类映射到多张表,这种情况一般是由于要考虑程序效率才这样做。在某些情况下划分多张表会提高性能,但如果执行涉及连接的操作则通常反而降低性能。
3)类间关系(继承、聚集、关联)的映射。继承关系的映射,一般有三种形式:①整个类层次使用一张表,类层次中所有类的所有属性均存放在该表中。②每个叶结点类使用一张表。③每个类使用一张表,该表只保存OID(对象标识)以及对应类自己的属性(不含所继承的属性)。关联与聚类关系的映射从关系范式的角度来看,区别仅在于耦合程度不同而已。聚类耦合程度高:通常对“整体”操作都伴随着对“部分”。关联则不存在这么高的相关度。
3 对象持久性的设计方案
为了将设计阶段的工作过程清晰的表达出来,该文简单的设计一个餐馆订餐小系统来说明整个设计过程。
第一步:标志那些数据需要持久性。
对象标识(OID)唯一标识关联对象/关系,在关系范式里该标识称为关键码(key),在对象范式里就是作为持久对象标识。OID的实现既可以是一个轻量级对象,也可以是整数、字符串等。OID设计的基本要求是唯一性和不变性。OID有3种层次的唯一性:1。在同一个类中具有唯一性。2。在同一个类层次中具有唯一性。3,在所有对象中均有唯一性。唯一性范围越大,则通常的开销也越大。例如:需要更长的计算机时间以获取OID,需要更多的存储空间以存放OID。OID的不变性是我们容易忽略的一个重要特征,因为任何业务逻辑含义都会发生变化,从而,任何对象标识不应含有任何业务逻辑含义。
在UML中类是作为指派持久性的基本单位。因为并不是每一个类都需要持久性,所以在设计过程中用带标签的值来标志持久性,可以采用(名字、值)简写的方式来表示,名字为类名,值分别记为Persistent(持久的)和transitory(暂时的),其中默认情况下是transitory(如下图所示)。这一步的设计我们要注意的是两个持久类之间的关联也是持久的。
第二步:设计合适的数据库模式。
在数据库设计阶段,简单的设计4张表:Table(桌子) 、Customer(顾客)、Walkin(无预订散客)、Reservation(预约)。每一张表添加显式的对象标识(OID),实现链接时用这些对象标识作为外码(FK)。由于本文所设计的Booking类是一个抽象类,可以简单地将其具体之类映射为表。餐馆订餐小系统数据库模式设计结果为:
第三步:解决对象与关系的同步问题
这时要解决的问题是:哪一个对象的职责应包含往数据库存放或从数据库装入对象的功能?因为指派为已有的类会导致聚合性降低,所以引入一个新的类专门执行该职责。为每一持久类定义一个映射类(Mapper)。在设计模型中引入对象标识,从而在领域模型之外亦可实现持久性。为每一持久性类定义子类,在子类中添加对象标识。Mapper类处理具有持久性的子类。
第四步:持久性体系结构设计
Persistent子类和Mapper类依赖于它们所支持的类。它们应出现在业务逻辑层,但Restaurant类依赖于 Mapper类。将业务逻辑层划分为两个子包。从而尽量避免了子程序包Persistency的变化对子程序包Domain带来的影响。持久性体系结构图如图4。
4 结束语
实现重量型持久性对象本文推荐的解决方案是O/R+RDB。持久性对象的设计的过程为:1)标识哪些数据需要持久性;2)设计一个合适的数据库模式;3)解决对象与关系的同步问题,最后总结自己的持久性体系结构。该文所描述的持久性对象的设计过程可以为解决同类问题的提供参考。
参考文献:
[1] 宋波,刘杰,杜庆东.UML面向对象技术与实践[M].北京:科学出版社,2005.
[2] 理查德森. Java高级编程:Jdk5[M].沈文炎,译.北京:机械工业出版社,2006.
[3] 霍顿.Java2入门经典:JDK5[M].潘晓雷,译.北京:机械工业出版社,2006.endprint