... </row> ... </table> <table> ... </table> ... </database>
根据所用软件的不同,可以指定将各字段数据以子元素或属性存储,也可以指定这些元素或属性的名字。此外,采用基于表格映射方式的软件还可能允许在文件开始的地方包含表格或各字段的元数据,或者将其作为各表格或元素的属性。注意这里所说的“表格”是泛指的表格。当将数据从数据库中转到xml文件时,“表格”可以是任何结果集,反之,“表格”可以是普通的表格或可更新的视图。
基于表格的映射对存取关系型数据比较适用,比如在两个关系型数据库之间转换数据。其明显不足就是不适于与上述格式不符的xml文件。
5.1.2 对象-关系映射 (object-relational mapping)
所有支持xml的关系型数据库和某些中间件都可以使用对象-关系的映射方式。它将xml文件中的数据视为特定的对象树的模型。在这个模型中,元素及其类型、元素内容或混合内容(复合元素类型)通常被视为类。只具有pcdata内容的元素(简单元素类型)、属性以及pcdata都被当作简单属性。然后通过传统的对象-关系映射技术或sql 3的对象视图将该模型映射到关系型数据库。也就是说,类被映射到表格,简单属性被映射到字段,而值为对象属性被映射为成对的主键/外键(primary key/foreign key)。
(所谓“对象-关系映射”实际上名不副实。因为对象树可以被直接映射到面向对象型和层次型数据库,然而,但是由于大多数使用这种映射方式的主流产品使用的其实是关系型数据库,所以“对象-关系映射”也就广为人知。)
我们在理解这种映射所用的对象模型的时候要知道,这个对象模型不是文件对象模型(dom)。所有xml文件的dom都是一样的,而上述描述文件数据的模型对于每个dtd所定义的xml文件都不一样,例如,上述销售订单的模型是一个由四个类所组成的对象树--salesorder, customer, item, 和part, 如下图所示:
salesorder
/ | \
customer item item
| |
part part
在由同一个文件产生的dom中,对象树的组成是元素、属性和文本:
元素 --- 属性
(salesorder) (sonumber)
____/ / \ \_____
/ / \ \
元素 文本 元素 元素
(customer) (orderdate) (item) (item)
| | |
etc. etc. etc.
模型中的对象是否被实例化要取决于所用的软件。有些软件允许依据模型产生类,然后可以在程序中使用由这些类所产生的对象。在这些产品中,数据是在xml文件 - 对象 - 数据库之间传递的。其他产品是直接在xml文件和数据库之间进行数据转换的,对象只是作为这种过程的可视化帮助工具。生成这些中间对象是否有用完全取决于你的应用程序。
(根据sun的 java architecture for xml binding,xml文件与对象的绑定通常被称为xml数据绑定(xml data binding), 有些产品支持xml数据绑定,其中许多还可以在对象和数据库之间进行数据交换,更多的信息,请看 xml数据绑定相关资源 xml data binding resources.)
各种产品支持对象-关系映射的具体实现方法有所不同。例如:
- 所有产品都支持从复合元素类型到类,以及从简单元素类型和属性(attributes)到[类的]属性(properties)的映射。
- 几乎所有产品都允许你指定根元素不被映射到对象模型或数据库。如果你想在同一个xml文档中存储多个顶级对象时,这个包装元素(wrapper element)就显得有用了。例如,如果你想在同一个xml文件中存储多个销售订单,就必须把它们包装在一个根元素内。
当使用基于表格的映射的xml文件有多个表格组成时,这个包装元素就相当于<database>元素,这是因为根据目前的标准,xml文件只能有一个根元素。少数产品允许你在较低的层次上指定包装元素。
- 大多数产品允许你说明将[对象的]属性(properties)映射到xml文件中的属性(attribute)还是子元素。某些产品还允许你混合使用属性和子元素,其他的只允许你使用两者之一。
- 大多数产品允许xml文件和数据库的名字可以不同。少数产品要求必须使用相同的名字。
- 大多数产品允许你说明子元素在父元素中的出现次序,尽管如此,要建立多个内容模型仍是不可能的。幸好对于大多数以数据为中心的文档而言,所提供的内容模型已经足够。(当文件需要验证时,子元素的次序相当重要。)
- 某些产品允许你将复合元素类型映射到简单属性(properties)。当某个元素包含混合内容(例如销售订单中的<description>元素)时,这点相当有用。尽管<description>元素像xhtml一样包含子元素和文本,但最好还是将这个description视为单个属性,而不是把它分成许多碎块。