对于一些小型的项目,需要存储的数据字段和数据量可能都比较小,为了降低项目成本,或提高项目的独立性,开发人员希望能不依赖数据库进行开 发。此时,利用 XML Schema 进行数据存储便是一个非常好的解决方案。利用此方法可以直接把数据存储在 xml 文件中,然后把 xml 文件存放在磁盘的某个位置,这样会使得项目的部署与运行非常的方便。
本文会详细的介绍如何基于 xml schema 进行数据的存储,如何以面象对象的方式对 xml 文件进行操作,以提高项目的开发速度和准确度。 文中还提供了一些详细的代码示例来帮助读者了解开发的技术细节。
![]() ![]() |
![]() |
利用 XML Schema 存储数据的原理就是将数据存储在 schema 所定义的 xml 文档中, 但本文中所讲述的实现方法不会直接面对 xml,而是通过一些类以面象对象的方式实现存取操作,这些类是利用开发工具自动的生成的。本文会以 WID (Websphere Integration Development) 为参考,详细介绍如何构建一个 XML Schema,如何根据 schema 生成 Java 类,以及如何应用这些类进行数据的存取操作。总体来说,应用 schema 进行数据存储大致分为以下几个步骤:
- 创建一个合适的 schema 文件,来满足数据的存储需求
- 根据 schema 生成 Java 类,应用这些类以面象对象的方式对 xml 文件进行操作
- 对 xml 文件的保存。
本文会对上述三个步骤来进行详细的讲解。
![]() ![]() |
![]() |
应用 schema 存储数据首先要创建一个 schema 文件,schema 中要包含所有需要存储的数据字段。那么在创建 schema 的时候要考虑这些字段的组织结构,要使得这些字段的结构更为合理,使得后续的操作更为方便。对数据字段应加以分类,然后针对每类数据创建一个结构化对象, 就象在数据库中设计表一样,需要决定把哪些字段放在一个表中。在 schema 中,与数据库表相对应的对象是“ Type ”,每个“ Type ”中封装了一类数据字段。以一个简单的库存管理系统为例,为了实现这个系统,大概有五类数据需要存储:货物类别,每日售货记录,供应商信息,送货信息,退 货信息。在设计 schema 的时候,要针对每类数据创建一种 Type,以更加清晰的管理每种数据。
![]() ![]() |
![]() |
Schema 的创建可以有多种方式,既可以用文本工具手工编写, 也可以借助开发工具更快捷的创建。 WID 当中有一个创建 schema 的功能,可以应用它很方便的创建一个 schema 。在 WID 菜单中选择 : new – > other,在出现的对话框中,选择 : XML – > XML Schema,根据图中所示的步骤可以创建一个 schema 文件。下图所示为一个已经创建完成的 schema 文件,该 schema 中包含了上文提到的库存管理系统的五类数据(本文后续部分会以此 schema 为例进行讲解)。
上图所示为 WID 中的 schema 编辑器,它有左右两个编辑域:Elements 和 Types 。
1. Types 域是用来定义结构化对象的,把一些数据字段封装在其中。在编辑域中点击右键可以选择增加或删除一个 Type 。双击一个已经创建的 Type 会进入到 Type 的编辑器来对 Type 进行编辑。如下图所示:
在此编辑器中可以为一个 Type 添加或删除字段,修改字段类型。字段类型可以是基本类型,如 string,date ;也可以是已经定义的其他 Type 类型,如 Category 对象中的 supplier 元素的类型就是一个已定义的 Type 类型。 Type 编辑器提供了一个 Properties 域,可以利用它对字段方便的设置多种属性。
在图 1 所示的 Type 中有一个叫 StorageInfo 的 Type,它与其他五个 Type 有所不同,其他五个 Type 是用来封装数据字段的结构化对象,而 StorageInfo 是用来封装这五个 Type 的,而且 StorageInfo 这个对象是必不可少的。在封装这五个 Type 的时候要结合实际情况对他们组织一个合适的结构。可能只是简单的把它们放在第一层,也可能按照引用关系来排列一个多层次的结构。下图所示为 StorageInfo 的组织结构,本例中是把五个 Type 放在了第一层:
2.Elements 域是用来为 schema 定义一个根对象,其他的对象是通过这个根对象来获取的,但 Elements 域中的根对象只是一个简单简单的接口,需要为它指定一定 Types 域中的对象。图 1 中所示的 StorageInfo 对象便是供 Elements 域中的 StorageInfo 使用的。根对象的定义如下图所示:
![]() ![]() |
![]() |
为了实现以面象对象的方式操作 XML,需要根据 schema 来生成 Java 类。在 WID 中,根据 Schema 生成 Java 类非常简单,右健单击 schema 文件,在出现的菜单中选择 Generate -> Java,之后会出现一个对话窗口,如下图所示:
点击图中的 Next,会提示选择用来存放生成 Java 类的位置,之后点击 Finish,这样 Java 类便生成了。下图所示便为生成的所有的 Java 类。在 script 目录下面的类,以及 impl 和 util 两个目录中包含了这些类,应用这些类可以轻松的操作 XML 文件。
由 WID 所生的类看起来似乎比较复杂,但它们有各自的用途,知道了它们的用途后便可以对它清晰的分类:
- Type 所对应的 Bean 类
WID 会为图 1 中所示的每个 Type 定义一个相应的 JavaBean,例如:Catetory.java,DailyRecord.java,DeliverInfo.java 分别对应 schema 中的 Catetory,DailyRecord,DeliverInfo 。但这些类都只是接口,其中只有 getter,setter 方法的定义,并无具体实现。
- Bean 的实现类
Impl 目录中放的是 Bean 的实现类,对每一个接口都会有一个具体的实现。
- DocumentRoot
它表示 schema 的根对象,通过这个类可以得到 schema 中所有其它的对象,如 Category,DeliverInfo 等。
- ScriptFactory
用来创建所有的 Bean 对象,如 createStorageInfo(),createDeliverInfo().
- Util 类
Util 目录中有六个类,但只有其中的 ScriptResourceUtil.java 类会被经常应用,其他的五个类很少会用,所以不必太在意他们。 ScriptResourceUtil 是一个比较重要的类,会用它进行把 xml 文件加载到内存并转化成 Java 对象,同是也要用它把 Java 对象保存到 Xml 文件中。
![]() ![]() |
![]() |
在本文开头已阐述过,被保存的数据最终是存放在一个 xml 文件中,而且对 xml 文件的操作可以应用面象对象的方式进行。要实现以面象对象的方式操作 xml,首先要对 xml 文件加载并加以转换,然后获取根对象,这样便可取得所有其他的对象,对它们进行修改、删除或创建。获取根对象的代码示例如下,附件中包含了完整的代码,可 以下载以供参考:
|
得到 StorageInfo 对象之后,便可以以面象对象的方式进行数据的添加,删除,修改等操作。
得到了根对象之后便可以进行数据的增删改等操作。下面的示例讲解了具体的应用。
|
根据某个 条件修改对象。例如想要修改名称为“ Clothes ”的一个 Category 记录,可以按如下示例进行操作:
|
根据某个 条件删除一个对象。例如想要删除名称为“ Clothes ”的一个 Category 记录,可以按如下示例进行操作:
|
在对根对象 StorageInfo 对象操作完成后,需要对其进行持久化,以免数据的丢失。数据的持久化也就是将 StorageInfo 转换为 xml 并加以保存,这个步骤同样是应用 ScriptResourceUtil 这个类加以实现,见如下示例:
|
![]() ![]() |
![]() |
前面的示例中是把数据的内容直接存放到了 xml 文件中,这个文件是可读的,如果这不慎外泄可能会造成机密数据的泄露,可能会给公司造成一定的损失。所以避免这种情况,需要把 xml 文件进行加密,别人即使得到了 xml 文件,也无法理解其中的内容。在加密 xml 文件时,可以采用 base64 的方式,如下示例是经过修改的代码,它在保存和加载时都是针对一个已加密的 xml 文件。
因为 xml 文件在保存的时候已经应用 Base64 对其进行了加密,所以在加载文件的时候需要对其进行解密。
|
保存的时候用 Base64 对内容进行加密
|
![]() ![]() |
![]() |
应用程序在运行一段时间后,保存的数据会越来越多,保存数据的 xml 文件也会随之越来越大。如果 xml 文件过大会影响程序的执行效率,延长程序的响应时间,因此每隔一定的时间应该对一些历史数据进行归档。比如本文中的“每日售货记录”。这个记录每天都会产 生几百甚至几千条数据,那么隔一段时间应该对这些数据进行归档。对这些数据进行归档比较简单,通过写一段代码便可以实现。如下是代码示例:
|
![]() ![]() |
![]() |
XML 文件的存储位置不是一程不变的,因此在程序开发时,不要把 xml 文件存储路径直接写在代码中,而是应该把它放到配置文件中,这样当变更 xml 存储位置时,只需要改变一下配置文件中的路径就可以了,不必修改代码。
在设计 schema 时应尽量保持 schema 的简结,不要设计太深的层次,否则在操作时会带来不必要的麻烦。
应该定期做一下历史数据的归档,以减小 xml 文件大小,来提高程序的执行效率。
![]() ![]() |
![]() |
在一些情况下适当利用 schema 存储方案不但能使项目更加独立,不必依赖数据库的支持,也可以提高程序的执行效率。 虽然利用 XML 存储数据并不是一个新颖的方法,但是本文中所讲的内容会让读者了解到一个新的 xml 存储数据的实现方法。
学 习
- 在 developerWorks 的 XML 专区 中,获取用以提高您在 XML 方面的技能的各种资源。
- 参考 使用 XML: 安全编码实践,第 4 部分 获取 XML 安全实现的更多方法。
- 参考 使用 XML 进行数据存储与备份的实现获取 XML 数据存储的更多用法。
- 参考 使用 XML Schema 定义元素的基本知识 获得 XML Schema 的更多知识。
- IBM XML 认证:了解如何成为 IBM 认证的 XML 和相关技术开发人员。
- XML 技术库:developerWorks XML 专区提供了大量技术文章和技巧、教程、标准以及 IBM Redbook 。
- developerWorks 技术活动和网络广播:通过这些活动了解技术的最新发展。