虽然复杂的关系数据库到 SDO 的映射是可行的,但是这个例子使用的是一个非常简单的映射:每个数据库表都是一个 SDO 类型,表的每行是 SDO 数据对象,而每列是 SDO 属性。应用程序逻辑是相同的:通过执行预先定义好的查询从数据库中读取、打印并更新数据(将“Adam”改为“Kevin”),将更改保存到数据库。数据库查询返回 CUSTOMER 表中的两行:
| CUSTOMER ID(整数,主键) | CUSTOMER FIRSTNAME(字符串) | CUSTOMER LASTNAME(字符串) |
| 1 | Adam | Smith |
| 2 | Baker | Street |
下面给出了带有解释的 SDO 实现。
rdbService 查询数据库以获得数据。 |
|
| 相同的数据可能已经用 XML 等价地表示了。 |
|
| 打印每个客户名。 |
|
将第一个数据对象的 FIRSTNAME 设为 Kevin。中间件更新变更摘要(这里并没有显示出来)来指示改变。 |
|
| 将更新的数据写入数据库。 |
|
现在数据库包含:
| CUSTOMER ID(整数,主键) | CUSTOMER FIRSTNAME(字符串) | CUSTOMER LASTNAME(字符串) |
| 1 | Kevin | Smith |
| 2 | Baker | Street |
注意,第一行已经被更新了。
如果在我们的示例应用程序已经获得数据图之后,另外一个应用程序访问数据库并更改了值会怎么样?在写入时,数据访问服务检查变更摘要来决定如何对数据源应用更新。数据库可以使用开放式并发控制 (optimistic concurrency control) 来确保这个改变之前最后包含的值是“Adam”(否则,另外一个应用程序可能先改变数据,可能在该应用程序中需要某些错误恢复)。某些服务实现了更为高级的开放式并发形式;变更历史记录提供了那些算法所需要的原始值。
使用 EJB 时,SDO 作为 DTO(也称作值对象)J2EE 设计模式。一般来说,访问实体 EJB(Entity EJB)的每个属性的开销非常大,所以传输几个数据图中的 SDO 对象效率更高。会话 EJB(Session EJB)可能有方法产生和使用 SDO 图来更加高效地直接访问实体 EJB。Customer 实体 EJB 封装了对 Customer 记录的数据库访问。会话 EJB 提供了访问方法来从 Customer 实体 EJB 产生和返回 Customer SDO 图。
示例 9: 返回 SDO 和由 SDO 更新实体 EJB 的会话 Bean 接口
public interface CustomerSession ...{
Customer getCustomerByID(String customerID);
Customers getCustomersByLastName(String lastName);
void updateCustomers(Customers customers);
}
Customers 是包含若干客户的 SDO 根数据对象。Customers 的 List 包含 Customer 数据对象。ChangeSummary 用来记录对 Customer 对象所做的全部更改,包括任何的添加、删除或更新。updateCustomers() 方法利用所做的更改来更新 Customer 实体 EJB,并且可以在一个事务中批处理对数据源的更改。
示例 10:使用 Java 的 Customer 的 SDO 类型定义
总结public interface Customers ...{
List<Customer> getCustomers();
ChangeSummary getChanges();
}
SDO 为所有数据源启用了对应用程序数据的统一访问和公共编程模型,而不管数据存储在何地以及如何存储。SDO 利用了 XML 的简易性,而又没有引入 XML Schema 的复杂性或序列化的性能问题。通过同时使用 SDO 和 SOA,可以将系统编程任务从业务逻辑中分离出来,并且将其封装在可重用的服务之中,而不是所有编程人员都必须掌握这些技能才能入门。它们在没有陷入技术和实现细节的情况下简化了业务应用程序的编程,防止了技术改变产生的影响。有了 SDO,业务应用程序就是名副其实的业务应用程序。
