| 提供一流的在线用户体验可能需要访问多个数据源
所需的数据通常驻留于多个数据库,打包的应用程序或者其他信息仓库中。 访问并关联这些数据是现代企业面临的一个重大挑战。IT 界通常将这一问题称为企业信息集成(enterprise information integration,,EII)问题:企业应用程序需要能够容易地从一个分布式的且高度多样性的信息源的数据集合中访问并合成特定商业实体的相关信息。为满足这一需求,BEA公司提供了Liquid Data for WebLogic。
Liquid Data提供了对关系数据库、Web 服务、打包的应用程序(贯穿于J2EE CA适配器和应用视图)、XML 文件及XML消息中数据的统一访问,而且通过一种自定义的功能机制,也能统一访问其余绝大多数数据源中的数据。为了集成和增强从一个或多个数据源中提取信息的能力,Liquid Data提供了所有企业数据源的默认XML视图,并包括了一个基于XQuery的图形化的“视图-查询”编辑工具。它还包括了一个分布式的XML查询处理器并提供了高级特性,例如查询结果缓存、数据源级别,及存储查询级别的访问控制。这篇文章着重强调了Liquid Data WebLogic 8.1的这个重要的新特性。
Liquid Data 8.1
BEA Liquid Data for WebLogic 8.1版本的主要课题是向应用程序开发人员提供它与BEA WebLogic Platform 8.1其余部分间的无缝互操作性。在此课题内,与其他WebLogic Platform组件的互操作性中有3 方面是关键的焦点:
1.使入门级的开发人员轻松使用来自Liquid Data查询的结果。
2.使Liquid Data 易于使用,以便用作Web服务中的企业数据访问层。
3.使Liquid Data 易于使用,以便在集成项目中更加灵活的使用数据。
WebLogic Platform 8.1 版本的主要课题是提供一种统一的集成开发环境,即BEA WebLogic Workshop IDE,开发人员能在其中创建包括门户、Web 服务,及集成组件在内的整个应用程序。 WebLogic Workshop IDE程序设计模型是基于Java控件的概念——设计视图中可视化的简单组件具有诸多方法、事件、及属性;生成和使用带注释的Java代码,可使开发人员不必编写复杂的J2EE底层结构代码,只需通过声明来指定所需的行为即可。Java控件提供了对J2EE资源,例如JDBC数据源、JMS查询、EJBs或Web 服务的简化访问。 应用程序开发人员还能创建新的控件,把业务逻辑封装到可重用的包中,以便供其他的应用程序开发人员使用。Liquid Data for WebLogic 8.1 提供了Liquid Data 控件,使得WebLogic Workshop应用程序很容易使用Liquid Data 查询。
除了提供新的Liquid Data 控件外,Liquid Data现在支持在查询中访问限制性文件和“in-flight” XML 段。同时,它还提供了一种方式,用于在开发查询和视图的过程中利用SQL存储过程和特定于厂商的SQL扩展。经过合理改进,Liquid Data的这一版本包括了对查询构建器UI可用性方面的重要增强。
在本文的后续部分,我们将使用Data View Builder (Liquid Data的查询构建器UI)构建一个分布式查询,然后在WebLogic Workshop IDE中创建一个Liquid Data 控件来封装这个查询。在创建完这个控件后,我们将演示用此控件创建门户、页面流、Web服务是多么简单。在本文的末尾,我们将看一看上面提到的一些其他特性和改进。
Liquid Data Java 控件
BEA Liquid Data for WebLogic 的Java控件允许应用程序开发人员在用BEA WebLogic Workshop IDE开发应用程序时,可轻松地使用Liquid Data查询。当使用Liquid Data 控件设计环境创建控件实例时,应用程序开发人员可以浏览Liquid Data服务器存储库并可选择一个或多个已存储的查询。然后这些被选择的查询可用做控件的方法。除此之外,控件也为应用程序提供了一种方法,可直接向Liquid Data服务器发送特定的查询。在以上两种情况下,都要利用WebLogic Workshop's XMLBeans技术把查询结果返回给应用程序。对于每种方法,返回类型都是一个XMLBeans实例,该实例是由Liquid Data 控件设计环境依据查询的XML Schema结果类型自动生成的。
对于以前从未接触过XMLBeans的人而言,它是BEA公司一项新的XML-Java绑定技术:以XML Schema为基础生成Java类,这些Java类提供了对Java 程序中的XML实例数据便利的、类型的访问。XMLBeans被设计成既支持对XML实例数据的类型安全的Java访问,又可支持对自身底层XML数据的访问,它结合了底层API例如SAX和DOM(提供完全访问)的最佳特性及Java绑定的便利性。当通过一个有效的基于光标的界面提供对数据的完全访问时,由XMLBeans生成的类型安全的Java类提供了对底层XML数据受约束的读/写访问。XML光标在底层XML数据中定义了一个位置,在此位置处程序可以对所选的XML数据执行各种操作(例如,设置或获取其值,插入或删除XML段,将XML块复制到文档的其他部分)。Liquid Data 控件通过用XMLBeans传送它的查询结果,能使WebLogic Workshop应用程序开发人员创建页面流、门户、Web服务,通过调用Liquid Data控件获得的XML查询结果使工作流开发变得更加容易。
一个应用程序方案的示例
Avitek是一位在线电子零售商,他想要构建并部署一个新的客户自助服务的应用程序。 目的旨在通过向Avitek的Web站点添加客户自助服务的能力,来减少呼叫中心的开支。一旦某位客户登录进来,他(或她)应能查看他们的配置信息并检索他们的定购信息。要为Avitek构建这个客户自助服务的门户,我们将从为一位特定的在线客户开发一个CustomerOrder查询以检索该客户的配置及定购信息。
为了使示例简单,假设只存在两个包含有关客户自助服务门户数据的数据源:
· RTL-Customer: 一个包含客户配置信息的关系数据库
· ElectOrderService:一个面向打包的定购管理应用程序的Web服务,该Web服务包含了Avitek客户的电子定购信息
图形化的顾客定购查询
图1显示了如何使用BEA Liquid Data for WebLogic 8.1 的查询构建器工具——Data View Builder(DVB)来图形化地构造查询,该查询聚集了Avitek的客户自助服务信息页所需的全部信息。查询结果的形式由(右边显示的)它的目标模式决定,目标模式包含一个叫做CustProfile的顶层元素。 CustProfile还有一个子元素——Customer,它含有基本的配置信息,例如Customer_ID、First_Name、Last_Name、Email_Address。Customer元素本身也有一个子元素Customer_Order,它包含一个特定用户任一(全部)定购的汇总信息。该查询的客户配置信息来源于关系数据源RTL-Customer中的Customer表。某个特定用户的定购信息导致了对Web服务的方法ElectOrderService.getOrderSummary()的调用。这个Web服务调用把custid看成了一个来自Customer表中Customer_ID列的单个输入参数。此查询设计成了一个参数化的查询,该查询接受一个客户id作为输入并返回指定用户的配置及定购信息。
客户定购的Xquery源
作为图1的映射结果,清单1显示了由Liquid Data for WebLogic 8.1生成的XQuery的详细结构。XQuery中最顶层的FOR子句为每个客户都绑定了一个变量,前提是该用户要满足查询外部的Where判定,即客户ID与给定查询参数相匹配的那些客户。最外层的RETURN子句指定了查询的输出,该输出由来自RTL-Customer数据库的顾客数据和一个嵌套查询的结果组成。该嵌套查询从电子定购Web服务中提取定购数据。嵌套查询的Where子句确保了只查询客户感兴趣的定购信息,而且里部的RETURN子句只检索那些想得到的订购信息。清单2展示了这个查询输出一个例子。
|
清单1: 由 Data View Builder 8.1 生成的XQuery结构
namespace custorder = "http://www.avitek.com/custorder"
namespace elecOrd = "java:examples.ldi.webservice"
namespace Elect = "http://www.bea.com//examples/ldi/webservice/customerOrder"
<custorder:CustProfile>
{
for in document("RTL-CUSTOMER")/db/CUSTOMER
where (-1 of type xs:string eq /CUSTOMER_ID)
return
<CUSTOMER>
<CUSTOMER_ID>{ xf:data(/CUSTOMER_ID) }</CUSTOMER_ID>
<FIRST_NAME>{ xf:data(/FIRST_NAME) }</FIRST_NAME>
<LAST_NAME>{ xf:data(/LAST_NAME) }</LAST_NAME>
<EMAIL_ADDRESS>{ xf:data(/EMAIL_ADDRESS) }</EMAIL_ADDRESS>
{
for in Elect:getOrderSummary(/CUSTOMER_ID)/result/*
return
<CUSTOMER_ORDER>
<ORDER_ID>{ xf:data(/elecOrd:orderID) }</ORDER_ID>
<SHIP_TO_NAME>{ xf:data(/elecOrd:shipToName) }</SHIP_TO_NAME>
<ORDER_AMOUNT>{ xf:data(/elecOrd:totalOrderAmount) }</ORDER_AMOUNT>
<STATUS>{ xf:data(/elecOrd:status) }</STATUS>
</CUSTOMER_ORDER>
}
</CUSTOMER>
}
</custorder:CustProfile>
|
|
清单 2: 结果清单
<prefix1:CustProfile xmlns:prefix1="http://www.avitek.com/custorder">
<CUSTOMER>
<CUSTOMER_ID>Steve</CUSTOMER_ID>
<FIRST_NAME>Steve</FIRST_NAME>
<LAST_NAME>Ling</LAST_NAME>
<EMAIL_ADDRESS>JOHN_4.com</EMAIL_ADDRESS>
<CUSTOMER_ORDER>
<ORDER_ID>ORDER_4_0</ORDER_ID>
<SHIP_TO_NAME>Steve Ling</SHIP_TO_NAME>
<ORDER_AMOUNT>486.65</ORDER_AMOUNT>
<STATUS>CLOSED</STATUS>
</CUSTOMER_ORDER>
<CUSTOMER_ORDER>
<ORDER_ID>ORDER_4_1</ORDER_ID>
<SHIP_TO_NAME>Tiffany Ling</SHIP_TO_NAME>
<ORDER_AMOUNT>486.65</ORDER_AMOUNT>
<STATUS>CLOSED</STATUS>
</CUSTOMER_ORDER>
<CUSTOMER_ORDER>
<ORDER_ID>ORDER_4_2</ORDER_ID>
<SHIP_TO_NAME>Steve Ling</SHIP_TO_NAME>
<ORDER_AMOUNT>456.65</ORDER_AMOUNT>
<STATUS>CLOSED</STATUS>
</CUSTOMER_ORDER>
<CUSTOMER_ORDER>
<ORDER_ID>ORDER_4_3</ORDER_ID>
<SHIP_TO_NAME>Tiffany Ling</SHIP_TO_NAME>
<ORDER_AMOUNT>706.65</ORDER_AMOUNT>
<STATUS>CLOSED</STATUS>
</CUSTOMER_ORDER>
<CUSTOMER_ORDER>
<ORDER_ID>ORDER_4_4</ORDER_ID>
<SHIP_TO_NAME>Steve Ling</SHIP_TO_NAME>
<ORDER_AMOUNT>756.65</ORDER_AMOUNT>
<STATUS>OPEN</STATUS>
</CUSTOMER_ORDER>
<CUSTOMER_ORDER>
<ORDER_ID>ORDER_4_5</ORDER_ID>
<SHIP_TO_NAME>Tiffany Ling</SHIP_TO_NAME>
<ORDER_AMOUNT>756.65</ORDER_AMOUNT>
<STATUS>CLOSED</STATUS>
</CUSTOMER_ORDER>
</CUSTOMER>
</prefix1:CustProfile>
|
现在,我们已经成功地设计并测试了这个查询,我们能够把这个查询以及与它相关的目标模式作为一个已存储的查询部署到Liquid Data 服务器。从DVB直接部署一个已存储的查询是Liquid Data 8.1的一项新功能。一旦部署完成,对使用WebLogic Workshop IDE中的Liquid Data 控件的应用程序来说,该查询就会可立即变为可用的,因此我们现在开始着手创建一个Liquid Data Java控件。
创建Liquid Data 控件
我们已经使用DVB部署了Avitek客户定购查询,现在准备运行BEA WebLogic Workshop IDE,并开始用Liquid Data for WebLogic 8.1 控件创建一个预期的应用程序。为了创建一个Liquid Data控件的实例,我们将从在WebLogic Workshop中创建一个新的默认应用程序并在其中创建一个叫做orders的文件夹开始。然后,当我们要求WebLogic Workshop创建新的Java控件时,可通过从控件选项中选择Liquid Data来创建一个新的控件。完成这些工作后,点击“Next”按钮,屏幕上将会出现第二个画面,要求你在本地和远程liquid Data服务器之间选择其一。Liquid data 支持两种部署方案。既可以作为最终的应用程序驻留在同一台服务器上,也可驻留在远程服务器上。在本例中,我们选择本地服务器选项,然后单击“Create”。然后会出现Liquid Data控件创建过程的第三个屏幕画面,它允许我们浏览已部署在Liquid Data服务器的存储库中的存储查询。此时,在创建Liquid data 控件时,我们可从中选择一个或多个存储查询并把它们转换成方法。图2展示了从一组Liquid Data 查询中进行选择的对话框。
我们现在选择查询crm.CustOrder并按下“Finish”按钮;用于定义期望的Liquid Data控件实例的Java源代码将被作为文件CustOrder.jcx来创建。正如先前所述的,创建这个控件的同时会自动生成与关联于查询的目标模式相关的XMLBeans类。这些XMLBeans类为遍历由查询返回的XML数据提供了键入的存取器方法。清单3展示了Liquid Data 控件JCX文件的内容。假定在创建这个控件时,我们所选择的仅仅是一个查询,这个JCX文件仅仅定义了一个方法,该方法与我们所选择的查询所对应。方法的名称将会默认为查询的名称,但开发人员也有权更改方法名称。注意,这个CustomerOrder()方法接收了一个变量——Customer ID(为存储查询CustomerOrder输入的参数),并返回了类型CustOrderDocument(由查询的目标XML模式生成的XMLBeans类集合的根文档类型)的结果。JCX文件中的方法注释包括存储查询的名称及其XML模式的副本。
|
Listing 3: JCX Listing
/* Generated methods corresponding to stored queries.
*/
/**
* <?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd = "http://www.w3.org/2001/XMLSchema"
xmlns:custorder="http://www.avitek.com/custorder"
targetNamespace="http://www.avitek.com/custorder" >
<xsd:element name="CustProfile">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="CUSTOMER" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="CUSTOMER_ID" type="xsd:string"/>
<xsd:element name="FIRST_NAME" type="xsd:string"/>
<xsd:element name="LAST_NAME" type="xsd:string"/>
<xsd:element name="EMAIL_ADDRESS" type="xsd:string"/>
<xsd:element name="CUSTOMER_ORDER" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="ORDER_ID" type="xsd:string"/>
<xsd:element name="SHIP_TO_NAME" type="xsd:string"/>
<xsd:element name="TOTAL_ORDER_AMOUNT" type="xsd:decimal"/>
<xsd:element name="STATUS" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
*
* custID java.lang.String
*
* :Stored-Query Name="crm.CustOrder"
*/
com.avitekcust.custorder.CustOrderDocument CustOrder(java.lang.String custID);
|
一旦创建了这个Liquid Data Java控件实例,就可以在开发WebLogic Workshop应用程序,例如页面流、门户、Web 服务和工作流中使用它。
创建Web应用程序
BEA WebLogic Workshop 8.1为开发那些使用JavaServer Pages(JSP)、页面流、分割表述、业务逻辑、导航控制逻辑的Web应用程序提供了工具,这有助于将应用程序的复杂度降到最低限度。WebLogic Workshop中的页面流允许开发人员将Web应用程序的用户界面代码从其导航控制逻辑和其它业务逻辑(可能包括数据聚合代码)中分离出来。用户界面代码将放到它所归属的JSP文件中。导航控制逻辑可在页面流控制器(controller)文件(这是一个使用JPF文件扩展的特殊Java文件)中单独实现。数据聚合逻辑可以在一个liquid Data 控件中实现。在此部分中,我们将遍历创建一个Web应用程序的过程,该应用程序使用Liquid Data 控件进行数据聚合,并使用页面流进行数据表述。
指定一个Liquid Data 控件,右击该控件的JCX文件,WebLogic Workshop中将会出现一个二选一的提示:生成页面流,或者生成测试JWS(Java Wep 服务)文件。如果我们选择生成页面流选项,WebLogic Workshop就会运行它的页面流生产向导,来指导用户创建基于Liquid Data控件的页面流。WebLogic Workshop产生的默认页面流包括若干JSP,它们允许用户为控件方法的输入参数键入值,然后调用这些方法。然而,生成的JSP并不关心结果的格式,而只是在XML字符串格式中显示返回的结果。在本例中,我们所设想的格式――结果页上有一个标题以便为特定的客户显示Customer的配置数据,并同时显示一个列有其所有定购信息的表单。
为了在JSP结果页中按要求格式化查询的XML结果,我们需要在页面流中声明一个Customer类型的公有变量,以便可在WebLogic Workshop的页面流属性面板中访问它。当在源代码中声明这个变量并将查询结果赋值给它后,需要创建一个表以格式化标题信息。在标题块中,我们将简单地创建一个具有四行、两列的表。第一列包含Customer信息的标号,第二列包含实际的值。这些值可从属性数据面板的Customer对象中拖放到表中。如图3所示,我们需要从属性数据面板的Customer对象中把CustomerOrderArray元素拖放到Order Information表中。当我们把CustomerOrderArray元素拖动到JSP上时,将会弹出一个RepeaterWizard向导以引导定购表的创建。RepeaterWizard 向导将为我们提供各种选择,包括选择我们想显示的字段以及要使用的格式化风格。至此,我们已经完成了对JSP页面的格式化工作,并可测试我们的应用程序了。图4展示了运行最终的Web应用程序的输出。它显示了使用一个标题块和一个细节块来格式化的结果,其中标题块包含客户的配置信息,细节块包含与客户相关的所有定购信息。注意到在创建所需的客户自助服务应用程序时几乎不要求编写多少实际的代码,这是十分有趣的一点。
一旦我们创建了Liquid Data控件,那么再创建一个与之结合的门户、Web服务或者工作流是同样容易的。在任何一个其他WebLogic Workshop项目中使用Liquid Data查询的范例都和我们为创建Web应用程序所展示的的范例相同。
另外一些值得关注的liquid Data 特性
Liquid Data for WebLogic 8.1中, 除了增加了Liquid Data控件——这个核心的新功能之外,这个版本中还添加:在Liquid Data 环境中使用XML数据的几个新方式,并在几个关键方面对可管理性和性能做了改进。
限定性文件
当涉及文件数据源时,Liquid Data 1.0只支持XML 文件数据源。BEA Liquid Data for WebLogic 8.1添加了对限定性文件的支持,限定性文件是指包含一个预定义的字符作为数据分隔符的文本文件。限定性文件一般从数据库、电子表格或类似于电子表格的其他应用程序中导出。现在可以在Liquid Data中创建用于查询的限定性文件数据源。这样的数据源关联的(部分暗指)XML模式,通过创建使用限定性文件数据源的查询,使限定性文件数据与其他Liquid Data数据源的合并成为可能。
复杂参数类型
复杂参数类型(CPT)是本版本中添加的另一个新功能。本质上,CPT使得把XML 数据作为Liquid Data查询的输入参数来使用变得可行。 CPT使定义任意(XML Schema)类型的XML数据流然后把这种类型的XML数据作为一个查询的输入变得可行。 一个典型的CPT使用案例可能是一个工作流,它接受一个XML消息并需要使用来自后端异构数据源的数据集合中筛选出的信息来富化此XML消息。
调用SQL数据源
BEA Liquid Data for WebLogic 8.1还为把SQL存储过程和SQL查询作为Liquid Data 查询和视图中使用的参数化数据源提供了支持。为了把SQL存储过程和SQL查询作为Liquid Data 中的数据源使用,BEA开发了一个SQL Call Description File(SQL调用描述文件SCDF)。SCDF就是一个XML文件,其中定义了一组SQL存储过程和(或)SQL查询的类型和功能。随后,这些SQL调用就同其它任何数据源一样可用于Data View Builder中绑定查询。
结束语
在本文中,我们看到了BEA Liquid Data for WebLogic 8.1是怎样使开发应用程序变得简单――这些应用程序包括Web 应用、门户、Web 服务和工作流 ,它们需要从多个异构数据源的中访问数据。 你可从网址http://commerce.bea.com/index.jsp下载BEA Liquid Data for WebLogic 8.1,并试用用它自己来开发应用程序。 |