BEA与IBM联合白皮书
2003年11月
作者:
John Beatty,BEA
Stephen Brodsky,IBM
Martin Nally,IBM
Rahul Patel,BEA
简介
服务数据对象(Service Data Objects,SDO)[1]是一种统一各种数据源类型中的
数据编程的编程模型规范,它提供了对常见应用模式的有力支持,并允许应用程
序、工具和框架更轻松地查询、查看、绑定、更新和内省数据。本白皮书讨论了
SDO背后的驱动因素,呈现了SDO架构,并讨论了提供给业内供应商的进一步增
强SDO的机遇。
驱动因素
虽然Java™平台和J2EE提供了大量的数据编程模型和API,但是这些技术都是分
散的,而且通常不能服从于工具和框架。此外,其中的一些技术可能难以使用,
而且可能功能不够丰富,无法支持常见的应用需求。SDO旨在创建一个统一的数
据访问层,以一种可以服从工具和框架的易用方式为不同的数据源提供一种数据
访问解决方案。SDO不是为了满足替换底层数据访问技术的需求而开发的(参见
下面“与其他技术的关系”一节)。SDO的目标是:
对异构数据源的统一数据访问。当 前的数据编程技术或多或少都是特定于数据源
类型的。但是,在实际应用程序中,数据通常来自于各种数据源,包括关系数据
库(通过JDBC [2]、实 体EJB [3]或其他持久性框架访问)、定制的数据访问层(使
用各种常见的设计模式来实现)、 W eb服务(通过JAXRPC
[4]或其他方法访问)、
XML数据存储区、JMS [5]消息和企业信息系统(通过JCA [6] Resource Adapter
或通过一些定制的API访问)。这种异质性对应用程序开发人员提出了严重的挑
战,因为他们需要学习和使用大量不同的编程模型。过多的数据访问API也对试
图自动化诸如绑定UI组件到后端数据源(例如:JSR227
[7])之类的常见数据编
程任务的工具和框架造成了很大挑战。因此,一个与数据源类型无关的、表示数
据集合的通用工具可以为应用程序员提供更简单的统一编程模型,并为工具和框
架提供在不同的数据源中以一致的方式使用的机会。
对静态和动态数据API的统一支持。静态的强类型接口可以为应用程序员提供一
种使用编程模型的简单方式。例如,实体EJB、JDO [8]、Hibernate [9]以及其他
对象/关系持久性机制提供类型化的Java数据接口(例如,account.getFirstName()或
account.getBalance()), 这为开发人员提供了一种方便的编程模型。相比之下,J DBC
的ResultSet 和RowSet 接口只提供了动态的非类型化数据API ( 例如,
rs.getString(“FIRST_NAME”)或rs.getFloat(“BALANCE”))。类似地,J AXB [10]为XML
数据提供了代码生成的Java接口,这使XML数据编程比使用DOM或SAX API更
简单。
但是,只有静态数据API或只有动态数据API是不够的:两者都是必需的。静态
数据API提供应用程序员所需的易用性。但是在某些情况下,静态Java数据接口
既不可行也不适合。例如,对 于事先不知道结果数据的类型的动态查询,静态Java
数据接口就不可行。因此,统一的数据编程技术需要同时无缝地支持静态和动态
数据API。
对工具和框架的支持。当 前的数据编程技术不服从用于各种数据源类型的工具和
框架。工具和框架需要几个重要特性:
对跨异构数据源的数据的统一访问。因为实际应用程序所使用的数据来自于
各种数据源,框架需要依赖于统一的数据表示。
动态数据API。如前所述,框架最好使用动态数据API,因为框架对特定数据
是通用的,而代码生成的接口通常是不适合或不可行的。
简单的内省(或元数据)API。框架通常需要内省数据的“形状”以执行数
据呈现、可更新的表单、数据绑定等等。
对断开编程模型的支持。许多应用程序自然地包含数据访问的断开使用模式:应
用程序读取一组数据,将其在本地保留一段短的时间,操纵数据,然后再将更改
应用到数据源。例如,这在基于Web的应用程序中是非常常见的模式:一个Web
客户端请求查看一个表单,一个Servlet或JSP请求本地读事务中的数据,并将数
据呈现在HTML表单中,Web客户端提交对表单的更新,Servlet或JSP使用新的事
务更新数据。最佳实践通常要求对该场景使用乐观并发语义,从而提供具有适当
业务级语义的高级别并发。
目前没有哪一种数据访问技术能够同时提供这种断开的乐观模型以及前述的其
他特性。JDBC扩展(通过JSR114
中的CachedRowSet,“RowSet Implementations”
[11])提供了断开模型,但是如前所述,JDBC不能满足异构数据访问或易用性
的要求。类似地,许多对象/关系持久性机制(例如,许多实体EJB实现、JDO、
Hibernate等等)虽然支持乐观并发语义,但是它们不提供必需的统一数据访问特
性。
对基于常见设计模式的定制数据访问层的支持。许 多应用程序使用常见的设计模
式(例如,T ransfer Object [12]、T ransfer Object Assembler [13]、D ata Access Objects
[14]以及Domain Store [15])来构建定制的数据访问层。当应用程序需要与物理
数据源隔离时通常都使用这些模式。实现数据访问层通常需要大量的定制代码,
其中许多都是可以自动化的。此外,这些定制的数据访问层应该能够集成到工具
和框架中。
应用代码与数据访问代码的去耦合性。为了获得可重用性和可维护性,应用代码
应该与数据访问代码分离。数据访问技术应该服从这一关注点分离。
架构
SDO具有一个可组合的(对应于单片式)架构。核心SDO规范提供了适用于各种
类型的数据源的基本API。例如,核心SDO规范没有指定一种特定的查询语言或
特定的后端存储区。因此,查询语言可以使用SQL,也可以使用XPath [16]或
Xquery [17],或者其他任何查询语言。存储区可以使用关系数据库,也可以使用
对象数据库或XML数据源。SDO架构的基本原则是,尽可能地使用常见资源,
必要时也允许使用特定于数据源类型的资源。核 心SDO规范创建了使这种灵活性
和简单性成为可能的内核。
SDO佳构基于断开数据图的概念。在断开数据图模式下,客户端从数据源检索数
据图(即,树结构或图结构的数据集合),更改数据图,然后可以将对数据图的
更改应用到数据源。更常见的是,使用乐观并发语义执行更新,这意味着,如果
有任何的底层数据在客户端应用更改之前被更改,更新就会被拒绝,应用程序就
必须采用纠正措施。乐观并发语义是一种自然的语义,对于大多数业务应用它都
运行良好。
对数据源的访问是由一种称为数据中介服务(data mediator service)的组件提供
的。数据中介服务负责查询数据源、创建包含数据对象的数据图,并将对数据图
的更改应用到数据源。
客户端通常是与数据中介服务断开的:只在检索或更新数据图时才连接。
图1:断开的数据图架构
SDO提供了一组核心组件和服务,然后使用SDO支持的工具和框架进行扩展。
SDO架构包括:
SDO核心。核心SDO规范[1]包含程序员常用的基本组件,包括表示数据的数
据对象(Data Object)和表示数据图的数据图(Data Graph)。SDO规范还提供
了一个元数据API,它允许客户端自省数据模型。SDO元数据API使工具和框架
能够以统一的方式处理不同的数据源。元数据API支持来自其他综合性更强的元
模型(比如:W3C XML Schema [18]、SQL关系模型以及Essential Meta Object
Facility (EMOF) [19])的基本概念。
SDO数据中介服务。数据中介服务提供对数据源的访问。数据中介服务通过
从后端数据源读取数据而创建数据图,还可以基于对数据图所做的更改而更新数
据源。数据中介服务可以以各种形式和大小出现,而且还可以包括(例如)可以
对XML数据源进行读写的XML中介、对基于JDBC的数据源进行读写的关系中
介、根据应用定义的实体模型,甚至是接受XML查询并读写各种XML和非XML
数据源的中介。针对数据中介服务的规范已经排在SDO的路线图上了。
SDO支持的工具。SDO支持的工具包括代码生成器、元模型转换器、模式转
换器、数据建模工具、模式建模工具等等。
SDO支持的运行时和框架。运行时和框架使用SDO中的各种组件执行各种任
务,比如到UI组件的数据绑定。SDO架构是使这些运行时和框架具有这些能力的
关键因素。
图2:SDO以及Java平台
该架构中的各种组件包括数据对象、数据图和数据中介服务。此外,元数据也发
挥着重要作用。这些组件具有以下功能:
数据对象。数据对象保存实际数据,包括基本值以及对其他数据对象的引用。
数据对象还拥有对其元数据的引用,这允许内省数据对象以获取有关数据类型、
数据关系和数据约束的信息。
数据图。从概念上来说,数据图是一组提供组件之间或层之间的传输单元的
数据。具体来说,数据图是一个多根的数据对象集合。数据图记录所有对数据的
更改,包括新的数据对象、被更改的数据对象以及被移除的数据对象。
元数据。关于数据对象的元数据使开发工具和运行时框架能够内省数据,包
括数据类型、关系以及约束。SDO提供了一个通用的跨异构数据源类型的元数据
API来支持一般的工具和框架。
数据中介服务。数据中介服务负责与数据源交互以生成呈现数据的数据图。
中介还负责将对数据图的更改应用到数据源。
图3:SDO解决方案中的组件
SDO中对象的关系可以用UML模型表示:
图4:核心SDO组件的UML模型
数据对象
数据对象将数据保存为一组属性。这些属性包括基本值(比如XML属性和XML
元素内容)以及指向其他数据对象的引用(例如,PurchaseOrder数据对象可能有
一个Customer属性)。对于XML数据来说,数据对象通常表示一个元素、元素
的属性、简单类型子元素的值以及指向表示复杂类型子元素的数据对象的引用。
对于关系数据,数据对象通常表示一行数据。外键会通过指向另一个数据对象的
引用来表示,表示另一个表中的一行。
可以使用SDO元数据API(下面将会介绍)来内省数据对象。这允许程序获得关
于类型、关系和约束的信息。注意,内省不一定只限于SDO元数据API:一些实
现可能提供到本地元数据的访问,比如XML Schema对象模型。但是,SDO元数
据API提供了最常用到的元数据,因此只在需要的时候才应该转向其他元模型。
数据对象起码要提供一个动态数据API来读取和修改对象,包括对象的属性。该
动态API使用简单Xpath表达式在数据图中定位数据对象。可以从模型或模式(例
如:SQL关系模式、XML Schema定义、EMOF模型等等)生成数据对象的静态
Java接口。这将在开发时提供一个用户友好的API。例如,给定一个Purchase Order
的XML Schema定义,就可以生成PurchaseOrder Java接口。类似地,给定
PURCHASE_ORDER表的JDBC元数据,就可以生成PurchaseOrder Java接口。核
心SDO规范没有为数据对象定义Java接口生成。可以使用现有的Java接口生成解
决方案和规范,并 将其与SDO集成(例如,JA XB)。 例如,存 在许多从XML Schema
定义生成Java接口的解决方案。针对SQL关系数据以及来自其他数据源的数据的
Java接口生成也是可能的。
注意,数据对象的静态Java接口并不总是需要和适合的。动态数据API很重要是
因为代码生成并不是对所有场景都适合的。在 很多情况下运行时框架会内省元数
据并使用动态数据API。但是,静态类型化的接口为程序员提供了开发时的易用
性(例如,编译时类型校验、代码自动完成功能的可用性等等)。
数据对象具有丰富的关系支持,包括对1:1、1:n和n:m关系的支持。数据对象管
理关系,包括关系反转。例如,假设数据对象A引用了数据对象B,而B保存对A
的反向引用。那么,程序将从A转向B再转向某个数据对象C。在该场景中,B的
关系将自动被更改为从A到C。包含(或所有)关系也是受支持的,这使中介能
够做出正确的决策(例如,级联删除)。
数据图
数据图表示一组数据。更确切地说,它保存一组数据对象。
数据图通常是系统中组件之间的传输单元。就 此来说,数 据图负责记录更改摘要。
数据图可以有选择地跟踪数据图中所有数据对象的更改历史。通常可能由希望将
更改应用到后端数据源的数据中介服务以更改摘要(Change Summary)、数据
图属性的形式访问该更改历史。更改摘要提供关于添加、移除和更新了哪些数据
对象的信息。对于更新的数据对象,更改摘要将为更新后的属性同时提供以前的
值和新值。
元数据
有时会按照实例数据、元数据和元模型等各个层来描述数据。最底层是数据本身
或实例数据。这类数据服从一种由元数据描述的数据模型或模式。而元数据本身
服从于一种称为元模型 的模型。
以XML作比,XML实例文档是实例数据,模式(例如,XML Schema Definition
或XSD)是元数据,模式语言(例如,W3C XML Schema)是元模型。类似地,
对于关系数据,结果集(ResultSet)或行集(RowSet)包含数据,数据定义就是
元数据(通过RowSetMetaData接口),而SQL关系模型则是元模型。
图5:数据、元数据以及元模型之间的关系
SDO提供了一个小型元数据API(即,一个元模型)。该元模型不打算像XML
Schema、SQL关系元模型或EMOF那样包含众多内容,而是提供应用程序和框架
进行常见内省任务所需的元数据的基本客户端视图。
它支持大量的用例,其中数据的常规内省非常有用。一个常见的用例是执行Web
UI组件与数据源之间的数据绑定的工具。S DO使这些数据绑定框架能够独立于其
本地元模型地处理XML数据、关系数据、JCA记录数据等等。
用例
SDO支持多种常见用例,下面将介绍其中的一些。
虚拟数据访问
SDO可以用于提供来自于多个异构数据源的统一聚合数据的虚拟数据访问架构
中。这是一种常见的架构模式,甚至底层数据源全部都是通过JDBC或实体EJB
访问的关系数据。一个“虚拟数据中介”可以支持丰富的查询语言,比如Xquery。
然后可以观察、内省、更新来自虚拟数据中介的数据图,然后将其发送回原始数
据源——SDO程序员不必知道或了解后端跨各种类型的数据访问的复杂性。这在
由于各种原因(包括技能、安全性和管理方法)“数据供给”功能正式与“数据
使用”功能分离的企业环境中是一个极为关键的要求。此外,这种分离在面向服
务架构(ServiceOriented
Architecture,SOA)实现中也非常重要。SDO提供了统
一的客户端数据和元数据API以支持在这种环境中使用工具、框架和运行时。
图6:将SDO用于虚拟数据访问
关系数据库访问
SDO编程模型在对关系数据源编程方面的表现引人注目,因为它提供了断开的访
问模型,以及静态和动态数据API。实际上,S DO架构包含了许多广泛使用的J2EE
设计模式,包括Transfer Object、Transfer Object Assembler以及Domain Store。
关系数据中介服务可以提供基于SQL的查询功能。关系中介可以使用JDBC来实
现查询和更新:
图7:将SDO用于关系数据
SDO还可以与对象
关系持久性机制相集成,包括实体EJB、JDO和Hibernate。
图8:将SDO与实体EJB一起使用
读写 XML
SDO支持一个综合的XML编程模型,包括查询、读取和更新。在该架构下,XML
数据源可以是XML文件、本地XML数据存储区或者是具有XML功能的关系数据
库。注意,S DO打算提供比XQuery AP(I 比如JSR225,“
X Query API for Java” [20])
更高级的抽象。例如,一个可以与具有Xquery能力的XML数据源交互的“XML数
据中介服务”的工作原理可能如下:
图9:将SDO用于XML用例中
机遇
SDO规范提供了定制解决方案的核心。我 们期待供应商们构建可以进一步将SDO
与现有的和未来的数据访问技术相集成的数据中介服务和框架。
工具支持。SDO具有广泛的工具支持。Java接口生成工具是提供与SDO集成的静
态数据API所必需的。例如,可以提供一个从XML Schema生成静态数据API并与
SDO API集成的工具。同样,也可以提供一个从关系模式生成静态数据API并与
SDO API集成的工具。还有用于从UML [21]模型生成接口的工具。实际上,目前
已经存在许多这样的工具,只需扩展它们使其支持SDO即可。后续的规范可能会
定义如何从各种数据源生成Java接口,如果还没有适当的规范的话。
数据中介服务。SDO要有数据中介服务才有用处。最初出现的将是特定于供应商
的数据中介服务。现有的持久性机制,比如对象/关系持久性框架,可以被扩展
为支持SDO的数据中介服务。类似地,Xquery引擎也可以被转变为支持SDO的数
据中介服务。随着构建数据中介服务的经验的积累,对数据中介服务接口的标准
化将会大有帮助。
框架。SDO支持各种可以为常见的数据编程任务提供易用性的框架。例如,框架
可以使用SDO自动化( 使用Transfer Object、T ransfer Object Assembler、D ata Access
Object和Domain Store设计模式的)定制数据访问层。其他框架可以使用SDO将
用户界面组件(例如,网格、列表框等等)绑定到后端数据源。JSR227
就提出
了这样的框架,可以使用SDO来提供必需的基本元素。
与其他技术的关系
SDO可以与其他数据编程技术进行无缝集成。下面我们将介绍SDO如何与其他数
据编程技术和API进行关联和集成。
下面的表将SDO与其他数据编程技术作了一个比较:
模型 API 数据源 元数据API 查询语言
JDBC RowSet 连接 动态 关系 关系 SQL
JDBC CachedRowSet 断开 动态 关系 关系 SQL
实体EJB 连接 静态 关系 Java内省 EJBQL
JDO 连接 静态 关系,对象 Java内省 JDOQL
JCA 断开 动态 基于记录 未定义 未定义
DOM和SAX 不可用 动态 XML XML
infoset
Xpath ,
XQuery
JAXB 不可用 静态 XML Java内省 不可用
JAXRPC
不可用 静态 XML Java内省 不可用
SDO 断开 二者 任何 SDO元数据 任何
皆有 API , Java
内省
JDBC 与 JSR114
JDBC为关系数据源提供了一个带动态数据API的连接的编程模型。JSR114
(“RowSet Implementations”)提供了对JDBC的扩展,从而提供了SDO所支持的一
些— — 但是远非全部— — 特性。JSR114
提供了表示跨表连接的数据的
JoinRowSet和提供数据访问的断开模型的CachedRowSet。
SDO也提供这两个特性,但是它与JDBC和JSR114
有两个重要的区别: (a) JDBC
针对对关系数据源的数据访问,而SDO可以用于任何类型的数据源; (b) JDBC
只提供了一个动态数据API,而SDO自然地支持静态数据API和动态数据API。
关系数据的数据中介服务可能会使用JDBC或者是JSR114
来实现。
实体 EJB
SDO还可以通过一个与实体bean接合的数据中介服务与实体EJB一起使用。实际
上,该架构正是常用的Transfer Object和Transfer Object Assembler设计模式的一
个表现。在某些情况下,将SDO与关系数据中介服务结合使用就可以避免使用实
体EJB。但是,实体EJB提供了一个连接的事务型模型,对于某些应用来说这可
能更适合。
JDO、Hibernate 以及其他持久性框架
JDO、Hibernate以及其他对象
关系持久性框架提供了SDO所提供的大量特性。
例如,JDO和Hibernate都提供了方便的静态数据API。Hibernate和一些JDO实现
提供了乐观并发、断开模型。这些持久性框架可以被扩展为支持SDO的数据中介
服务,这样这些框架就可以用于SDO解决方案中了。
JavaXML
绑定
JavaXML
绑定框架(比如JAXRPC
、JAXB、SAAJ [22]、XML Beans [23],以及
Eclipse EMF [24]和XSD [25]工具)支持将XML数据绑定到Java对象。这些提供数
据访问的Java接口是从模式语言(比如XML Schema或RELAX NG [26])生成的。
这些生成的接口提供了一种对程序员友好的读取、写入和操纵XML数据的方式。
JavaXML
绑定框架可以被扩展以便与SDO集成。例如,JAXB可以被用作提供静
态数据API的工具,并被扩展以支持数据图和数据对象接口。
Xquery 与 JSR225
Xquery是即将发布的用于查询XML数据的标准,可以用于处理XML数据源。
Xquery也可以更广泛地用于任何数据储存库。因此,数据中介服务可以将Xquery
用作查询语言。
JSR225
(XQuery API for Java)是一个XQuery标准API的提案。该API将位于比
SDO更低的层,将会对SDO环境中的XML中介服务的标准实现大有帮助。在这
方面JSR225
的作用就好比JDBC对于关系中介的作用。
Web UI 数据绑定与 JSR227
JSR227
(“A Standard Data Binding & Data Access Facility for J2EE”)提出了一种
可以声明式地将Web用户界面组件绑定到异构的后端数据源的功能。例如,
JavaServer Faces组件(例如,一个网格组件)可以被绑定到关系数据或来自Web
服务的XML数据。SDO规范提供了可以使用JSR227
的底层要素。
JCA 与 JMS
JCA Common Client Interface (CCI)使用Record抽象来与企业资源传递数据。这些
记录没有特定的结构。对于SDO,客户端应用程序可以使用数据图与企业资源传
递数据。类似地,J MS也有一个非结构化的消息结构。S DO数据图可以用于在JMS
队列或主题中发送和接收数据。
参考资料
[1] http://dev2dev.bea.com/technologies/commonj/index.jsp
或
http://www.ibm.com/developerworks/library/jcommonjsdowmt/
[2] JDBC Data Access API,http://java.sun.com/products/jdbc/
[3] Enterprise JavaBeans,http://java.sun.com/products/ejb/
[4] Java API for XMLBased
RPC,http://java.sun.com/xml/jaxrpc/
[5] Java Message Service,http://java.sun.com/products/jms/
[6] J2EE Connector Architecture,http://java.sun.com/j2ee/connector/
[7] A Standard Data Binding & Data Access Facility for J2EE,
http://www.jcp.org/en/jsr/detail?id=227
[8] Java Data Objects,http://java.sun.com/products/jdo/
[9] Hibernate,http://www.hibernate.org/
[10] Java API for XML Binding,http://java.sun.com/xml/jaxb/
[11] JDBC RowSet Implementations,http://jcp.org/en/jsr/detail?id=114
[12] http://java.sun.com/blueprints/corej2eepatterns/Patterns/TransferObject.html
[13]
http://java.sun.com/blueprints/corej2eepatterns/Patterns/TransferObjectAssembler.ht
ml
[14] http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html
[15] Core J2EE Patterns: Best Practices and Design Strategies,第 二版,作者:D eepak
Alur、John Crupi和Dan Malks
[16] XPath,http://www.w3.org/TR/xpath
[17] XQuery,http://www.w3.org/TR/xquery/
[18] XML Schema,http://www.w3.org/TR/xmlschema1/
以及
http://www.w3.org/TR/xmlschema2/
[19] Meta Object Facility,http://www.omg.org/docs/ad/030407.
pdf
[20] XQuery API for Java,http://www.jcp.org/en/jsr/detail?id=225
[21] Unified Modeling Language,http://www.omg.org/uml/
[22] SOAP with Attachments API for Java,http://java.sun.com/xml/saaj/
[23] XMLBeans,http://xml.apache.org/xmlbeans/
[24] Eclipse Modeling Framework,http://www.eclipse.org/emf/
[25] Eclipse XML Schema Infoset Model,http://www.eclipse.org/xsd/
[26] RELAX NG Specification,
http://www.oasisopen.
org/committees/relaxng/
spec20011203.
html