xml——连接SQL和Web程序的桥梁
作者:Alexander PRokhorenko,Olexiy Prokhorenko
译者:Aaron Chu(acdemo@Gmail.com)
08/22/2005
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
英文原文地址:
http://dev2dev.bea.com/pub/a/2005/06/xml_bridge.Html
中文地址:
http://www.matrix.org.cn/resource/article/43/43673_XML_SQL_Web.html
关键词: XML SQL Web
摘要
过去几年XML技术作为Internet上交换信息的格式受到了极大的欢迎。今天XML常常被描述成一种孤立的技术,但它最初诞生的时候却是一种(介于HTML和SGML之间的)Internet技术。本文讨论XML如何被用作数据库和最终用户间的“通讯协议”。
当前最流行的关系数据库管理系统用SQL查询语言来与数据打交道。虽然面向XML(XML-oriented)的数据库已经面市,却不常见。而XML如此流行,关系数据库开发者也在为产品增加XML兼容性的过程中学习进步。本文考察其中一种途径:让数据库返回XML。示范代码中用到了一个Oracle数据库,它被假定是XML兼容的,能处理XML数据。
本文分为两部分。第一部分预备和Oracle数据库打交道的java代码:提交一个SQL查询,获取一个XML输出;第二部分专注于一个web程序:将从数据库获取的XML数据输出为HTML文本。
要求
本文中用到下列软件:
BEA WebLogic Platform 8.1 with SP4 ——作应用程序服务器。
Oracle 10g Database Server ——作数据库服务器。你可以用不同版本的服务器来试验代码;据我们所知,本方案不需要特定的版本。
Oracle XML-SQL Utility (XSU) ——XSU是一组充当PL/SQL包装(wrapper)的Java类,它允许查询返回XML包装起来的结果集或对象。
Oracle XML Parser, Version 2 ——Oracle的基于Java校验XML有效性的解析器(parser),支持XSL。一般来讲XSU和XML解析器是Oracle Developer Suite的一部分。
本文中的代码在微软Windows xp系统上运行,但只需要很小的改动也应该能在任何操作系统上正确工作。
我们假定读者是有经验的Java开发者,熟悉BEA WebLogic Server,并且有JDBC编程经验。
准备连接池(Connection Pool)和数据源
如果你熟悉JDBC连接池和数据源的配置,请跳过这一节。
首先需要配置连接池和数据源。代码稍后会用JNDI来获取数据源,这需要一点配置。我们要配置一个JDBC连接池来保持和数据库的连接。登入WebLogic的控制台并选择Service Configurations -> JDBC -> Connection Pools节点。
现在选择“Configure a new JDBC Connection Pool...”以创建一个新的连接池,在接下来的画面里选择数据库类型和驱动(图1)。
图1. JDBC连接池:选择数据库
可以看到多种不同数据库可供选择。我们需要的数据库类型(Database Type)是Oracle,并且将使用BEA的Oracle Driver(Type 4)。然后点“Continue”按钮定义连接属性(图2)。
图2. JDBC连接池:连接属性
在这个画面中,为JDBC连接池选择一个名字,并设置其它诸如数据库名和主机名、连接端口和口令等数据库参数。
这里并不创建一个新数据库和一组表,我们将使用Oracle的示例SCOTT/TIGER模式(schema)和EMP表。几乎每个Oracle安装中都有这个示例,因此不需要你再去配置。如果没有EMP表或者这个表是空的,可以用Oracle目录下的\sqlplus\demo\demobld.sql脚本重建这个表并装入数据,还可以用\sqlplus\demo\demodrop.sql删除原有的值。
配置好这些参数之后点“Continue”(图3)。
图3. JDBC连接池:连接测试
一般情况不必对这一页做任何改动,这是一个连接测试页(可以点“Skip This Step”跳过)。WebLogic Server显示了驱动类名、(JDBC驱动使用的)URL和身份验证(用户名和密码)以供核对。复核完这些参数后准备测试,点“Test Driver Configuration”按钮,如果一切正确,将看到“Connection SUCcessful”的信息。最后点“Create and deploy”按钮完成JDBC连接池配置。
完成了JDBC连接池的工作,现在我们需要创建相应的数据源。回到WebLogic Server控制台的主页,按照这个顺序选择:Service Configurations -> JDBC -> Data Source。在接下来的画面中点击“Configure a new JDBC Data Source”链接,将看到数据源配置成功页(图4)。
图4. 数据源配置成功页
要定义JDBC数据源名称和能找到数据源的地方——JNDI路径。务必记住JNDI路径,稍后将用它来建立一个与我们代码的连接。接下来选择“Continue”,然后选择正确的连接池和数据源关联。选中刚刚创建的连接池,再点“Continue”,下一页允许你选择部署数据源的服务器和簇。从列表里选中需要的一个,接着点“Create”。数据源已经创建好,我们准备写代码了。
准备独立(Stand-Alone)Java程序的环境
让我们給即将编写的小客户程序准备一个环境。为了能执行SQL查询和获取XML数据作为输出,将用到Oracle XML-SQL utility (XSU),需要配置环境变量CLASSPATH指向Oracle XML-SQL Utility的库(library)和Oracle XML解析器。一般情况下XSU可以在Oracle的目录\rdbms\jlib\xsu12.jar找到,XML 解析器在\lib\xmlparserv2.jar。还有我们在使用JNDI,需要在CLASSPATH中包括weblogic.jar文件,一般在WebLogic Server的安装目录下:\bea\weblogic81\server\lib\weblogic.jar。
典型的CLASSPATH 看起来会像下面这样:
CLASSPATH=c:\Program Files\java\jdk1.5.0_01\lib;.;
C:\DevSuiteHome\rdbms\jlib\xsu12.jar;
C:\DevSuiteHome\lib\xmlparserv2.jar;
C:\bea\weblogic81\server\lib\weblogic.jar;
考察独立Java程序的代码
在展示代码前,注意到Oracle中有两种处理XML的方法是有意义的。二者的区别很大,你应该采用适合你手头任务的办法。第一种办法是用Oracle的XSU,允许从任何SQL查询返回XML;第二种办法是用Oracle的XMLType列类型(column type)。
XMLType列允许将XML当做数据库中的一种本地数据类型。因此,这些列可以像其它类型的列一样参与查询Consequently。Oracle提供了XMLTYPE()函数来创建一个XMLType数据对象,同时还提供了其它处理这个数据类型的函数,比如XMLELEMENT()和XMLAGG()。从WebLogic Server的在线文档(The Oracle Driver)或技术网站(Oracle Technology Network)可以读到关于这种办法的说明和示例。本文将专注于使用XSU的方法。
下面是在Oracle数据库上执行SQL查询并产生XML输出所需要的全部代码(oraxml.java)。
1. import javax.naming.*;
2. import javax.sql.*;
3. import java.sql.*;
5. import oracle.xml.sql.query.*;
5. public class oraxml
6. {
7. public static void main(String args[]) throws SQLException, NamingException
8. {
9. String tabName = "emp";
10. int maxRows = 3;
11. Context ctx = new InitialContext ();
12. DataSource ds = (DataSource) ctx.lookup ("MyOra");
13. Connection conn = ds.getConnection ();
14. OracleXMLQuery qu = new OracleXMLQuery (
conn, "select EMPNO, ENAME from " + tabName);
15. qu.setMaxRows (maxRows);
16. qu.setRowsetTag ("EMPLOYERS");
17. qu.setRowTag ("PERSON");
18. String xmlString = qu.getXMLString();
19. System.out.println (xmlString);
20. conn.close ();
21. }
22. }
这段代码很简单。
11-12行获取一个JNDI名称为MyOra的数据源;13和20行分别建立和关闭连接;最有意思的是14-18行执行了一个所谓的“XML查询”;从技术上讲,这是一个经XSU转换为XML的SQL查询;14行初始化查询;15-17行设置XML文档的结构,15行设定返回的最大行数不超过maxRows,16和17行设定文档的根元素(root element)和项目分隔符(item delimiters);18行生成一个XML文档并将其放在xmlString变量中。就像你看到的这样,代码很简单易懂。(英文编者注:注意,这不是成品代码。最后应该在一个finally语句的括号中关闭连接。)
别忘记这段代码中用到了JNDI。作为一个独立的Java程序,必须安排一个命名提供者(naming provider)給它使用。我们将用WebLogic Server作为提供者,配置方法首先要建一个jndi.properties文件,然后确保可以从环境变量访问这个文件。如果CLASSPATH包含当前目录(.),就应该将jndi.properties文件放在当前目录中。这是一个jndi.properties 文件的内容:
java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
java.naming.provider.url=t3://localhost:7001
典型的编译命令和运行结果像下面所展示的这样(注意输出被限制为不大于maxRows):
C:\white\work\Java\xmlweb_src>javac oraxml.java
C:\white\work\Java\xmlweb_src>java oraxml
<?xml version = '1.0'?>
<EMPLOYERS>
<PERSON num="1">
<EMPNO>7369</EMPNO>
<ENAME>SMITH</ENAME>
</PERSON>
<PERSON num="2">
<EMPNO>7499</EMPNO>
<ENAME>ALLEN</ENAME>
</PERSON>
<PERSON num="3">
<EMPNO>7521</EMPNO>
<ENAME>WARD</ENAME>
</PERSON>
</EMPLOYERS>
现在来稍微了解一点Oracle XML-SQL Utility的细节。可以看出,要执行SQL查询并以XML格式输出的话,这是一个相当顺手的工具。当然,XSU绝非只有区区这么一点功能。它可以动态生成DTD(Document Type Definition,文档类型定义),也可以执行简单的转换。XSU还可以生成XML文档的字符串或DOM表示形式;将XML插入数据表或视图;更新或者删除数据对象中的记录;对一个给出的XML文档生成一组复杂的嵌套XML文档,并在平面表上创建对象视图,然后在这些视图上执行查询,从而将这些文档存储到一些关系表中。 从Oracle9i开始,XSU还支持对一个SQL查询生成XML模式(schema)。还有,在生成过程中支持XML属性。要完全搞懂如何用XSU的功能来满足你的需要请参考XSU的文档。
用XML搭桥的好处
作者想强调本教程中描述的XML转换方法的优点并解释为什么我们觉得它有用处。读者或许会这样问自己:“为什么要在这里要使用XML?为什么将它称为‘桥’?”最好的办法是通过一个小例子来解释将XML作为“桥”的优点。假设你现在有一个信息门户网站,设计这个门户的目的是为了将新闻从SQL数据库传达到最终用户;这些用户可能是任何人,包括使用WAP浏览器的移动电话用户,或者装备了现代浏览器的常规网上冲浪者。此外,你作为信息的所有者,可以将这些新闻转售出去,而且新闻标题要不一样,例如“News from the Acme, Corp.”和“Latest news from Big Company”或者别随便的什么。而要新闻本身却是没有改变,所以,技术上只是改变了“外观(look and feel)”,那为什么要为可能收到新闻的每一类最终用户都写一次代码呢?
现在你发现自己需要某种既能接受SQL又能生成不同数据格式的透明桥梁——这座桥是XML。你编写的servlet向数据库提出一个请求,接收XML输出然后将一个XSL模板应用在之上,为最终用户生成一个页面。这样需要改动的仅是一个XSL设计,没有别的东西。没有额外的代码,不会浪费时间。想和其他人共享你的新闻?主意不错,但何必允许别人访问你的SQL数据库?又何必费神解释数据库的结构呢?——只要简单地由基本的SQL查询生成并共享XML就行了。
准备web程序的环境
到这里已经成功的编写了独立程序的代码,能够执行SQL查询并生成XML文档,我们完成了一半的工作。下一步要掌握WebLogic Server中将XML转换成不同格式的选项,再构建一个web程序。现在有许多不同的处理XML流的技术,我们只关注其中一种——使用XSLT jsp标签(tag)的方法。
WebLogic Server提供这个小型JSP标签库就是为了在JSP中方便地访问XSTL转换器。可以用它将XML文档转换为HTML、WML,以及其它格式。首先看看怎么为我们的web程序准备一个能够利用这些工具好处的环境。
每有一个web程序就配置一次CLASSPATH不是个好办法,所以必须将要用到的Oracle数据库jar文件放到web程序的\WEB-INF\lib目录。同时还要从Oracle的主目录把\rdbms\jlib\xsu12.jar和\lib\xmlparserv2.jar两个jar文件拷进去。WebLogic Type 4 JDBC驱动没有和WebLogic Server一起被安装在主目录,但该驱动已经被自动加入到服务器的CLASSPATH中。
使用WebLogic XML标签的过程十分简单,并且在Developing XML applications with WebLogic Server站点有很好的说明文档。当然,为了读者更容易使用它,本文的二位作者会引导大家完成整个过程。
从WebLogic Server的安装目录将xmlx.zip文件拷到\bea\weblogic81\server\ext\。我们需要上述压缩文件中的xmlx-tags.jar文件,在命令行下将这个文件放到web程序的\WEB-INF\lib目录中:
C:\white\work\Java\xmlweb\xmlweb_war\WEB-INF\lib>pkzipc -extract
C:\bea\weblogic81\server\ext\xmlx.zip xmlx-tags.jar
PKZIP(R) Version 4.00 FAST! Compression Utility for Windows
Copyright 1989-2000 PKWARE Inc. All Rights Reserved. Shareware Version
PKZIP Reg. U.S. Pat. and Tm. Off. Patent No. 5,051,745
MaSKINg file attributes: Read-Only, Hidden, System, Archive
Extracting files from .ZIP: C:\bea\weblogic81\server\ext\xmlx.zip
Inflating: xmlx-tags.jar
最后在WEB-INF目录中还需要一个web.xml文件,用<taglib>标签引用xmlx-tags.jar文件,像这样:
<web-app>
<taglib>
<taglib-uri>xmlx.tld</taglib-uri>
<taglib-location>/WEB-INF/lib/xmlx-tags.jar</taglib-location>
</taglib>
</web-app>
你可以查看本文附带的示例WAR程序了解完整的例子(译注:xmlweb.war)。
编写web程序
本节的目标是将我们学到的关于在独立程序里产生XML的知识应用到web程序的构建中,另外还要将XML转换为HTML。首先大致看看这个web程序需要哪些文件。将用到的文件包括:\WEB-INF\web.xml (前面已经提到)、html.xls(XSL转换器用来产生HTML文件的样式表)以及index.jsp (这个web程序的主页)。
首先考察样式表。html.xls文件用来将转换XML文档以输出HTML文档。
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<table width="60%" border="1" cellspacing="0" cellpadding="1">
<tr>
<td align="center"><b>Employer No.</b></td>
<td align="center"><b>Employer Name</b></td>
</tr>
<xsl:apply-templates select="EMPLOYERS"/>
</table>
</xsl:template>
<xsl:template match="PERSON">
<tr>
<td align="center"><xsl:value-of select="EMPNO"/></td>
<td align="center"><xsl:value-of select="ENAME"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
正如在上面看到的,这个样式表匹配根元素,创建一个表格,每当与PERSON元素的模板匹配就插入一行。
利用这个文件我们可以从新的XML文档生成HTML文档。
我们这个web程序的主要文件是index.jsp,一个平常的JSP文件。现在看看用到的JSP标签,其中的XSLT JSP标签语法基于XML。JSP标签由一个开始标记、一个可选的主干和匹配的关闭标签组成。以<xslt>标签为例,拥有可选的(特定的)参数。比如xml,标明想转换的XML文件的位置(相对于web程序的文档根目录);比如stylesheet,标明用于转换XML文档的样式表达的位置——同样是一个相对于web程序文档根目录的位置。要了解标签和可选项的更多信息,可以参考在线文档(Using the JSP Tag to Transfer XML Data)中的“XSLT JSP Tag Syntax”一节。现在来看JSP文件:
1. <%@ taglib uri="xmlx.tld" prefix="x"%>
2. <HTML>
3. <HEAD>
4. <TITLE>:: An XML bridge ::</TITLE>
5. </HEAD>
6. <BODY>
7. <%@page import="java.sql.*"%>
8. <%@page import="oracle.xml.sql.query.*"%>
9. <%@page import="oracle.jdbc.*"%>
10. <%
11. String tableName = "emp";
12. int maxRows = 3;
13. Context ctx = new InitialContext ();
14. DataSource ds = (DataSource) ctx.lookup ("MyOra");
15. Connection conn = ds.getConnection ();
16. OracleXMLQuery qu = new OracleXMLQuery
(conn, "select EMPNO, ENAME from " + tableName);
17. qu.setMaxRows (maxRows);
18. qu.setRowsetTag ("EMPLOYERS");
19. qu.setRowTag ("PERSON");
20. String xmlString = qu.getXMLString ();
21. conn.close ();
22. %>
23. <x:xslt stylesheet="html.xsl">
24. <x:xml>
25. <%=xmlString%>
26. </x:xml>
27. </x:xslt>
28. </BODY>
29. </HTML>
第1行将稍后23行要用到的xmlx标签库包含进来。7至22行是从常规Java代码到JSP代码的转换(没有进行异常处理)。这里的语法有些小变化,此外没有别的。23到27行是实际显示的XML代码。23行配置XML输出并设定样式表为html.xsl。24到26行将取自数据库,等待转换的XML包含进来。正如你看到的,代码很浅显。
熟悉了代码,就要准备编译我们的web程序并部署到WebLogic Server上。一个这么简单的WAR程序只要手工编译就可以了。下面是创建xmlweb.war程序以备发布的步骤:
C:\white\work\Java\xmlweb\xmlweb_war>jar -cvf xmlweb.war .
added manifest
adding: html.xsl(in = 579) (out= 279)(deflated 51%)
adding: index.jsp(in = 935) (out= 486)(deflated 48%)
adding: WEB-INF/(in = 0) (out= 0)(stored 0%)
adding: WEB-INF/lib/(in = 0) (out= 0)(stored 0%)
adding: WEB-INF/lib/xmlparserv2.jar(in = 689990) (out= 645476)(deflated 6%)
adding: WEB-INF/lib/xmlx-tags.jar(in = 11106) (out= 9952)(deflated 10%)
adding: WEB-INF/lib/xsu12.jar(in = 456545) (out= 138160)(deflated 69%)
adding: WEB-INF/web.xml(in = 327) (out= 226)(deflated 30%)
现在,找到编译好的web程序WAR文件并部署到WebLogic Server。
这可以利用WebLogic控制台做到。部署好后在web浏览器中打开下面这个地址查看结果:
http://localhost:7001/xmlweb/index.jsp
应该能看到类似图5的情形。
图5. 部署web程序
正如上图展示的,从数据库中以XML形式获取的数据按漂亮的格式显示了出来。现在我们可以在很多地方用到这种技术,从简单的新闻聚合(news feed)到有模板和样式表的复杂列表引擎。
结语
本教程为读者奉上了整合SQL查询和XML转换器的基础知识,給出了一个可以用在你自己软件中的特性。XML技术本身在web程序方面有许多用处,而与数据库的整合使它成为更强大的工具。
下载
本文中的独立Java程序:xmlweb_src.zip:[下载文件]
文中的web程序:xmlweb.war:[下载文件]
作者介绍
Alexander Prokhorenko 是一位经过认证的专业人员,获得Sun系统管理员认证和Sun Java程序员认证。他的兴趣领域包括系统开发生命周期、IT项目管理、服务器和应用程序架构。
Olexiy Prokhorenko 是一位Sun认证企业架构师,同样获得了Sun Java程序员认证和Sun Web组件开发者认证。他的兴趣领域包括Web软件架构、高频变更需求的软件开发,以及异地外包团队的管理。 (出处:http://www.knowsky.com)