将JDBC结果集转换为XML
By Jeff Ryan 译:方威
介绍
XML已经成为不同平台应用系统之间数据交换的通用格试。随着应用向基于以XML为基础的服务转移,开发人员经常把各种各样的数据结构转换为XML或将XML转换他们所需要的数据结构.正如所说的那样,其中将关系型数据库中的持久化数据换换为XML非常普遍。怎样将关系型数据结构转化成XML呢?在这篇文章中,我们将编写一个工具,将关系型数据转换为XML文档。
虽然这个问题可以用多种语言实现,但我还是选择JAVA语言来结决这个问题,JDBC(Java Data Base Connectivity)提供了通用的API访问关系型数据库。其中有很多方法是我们需要的,可以用来将ResultSet转换成XML。
当然,在这个例子中我们需要一个运行的数据库。我决定用Pointbase。你可以用你手头上的任何一种关系型数据库如Access、MySQL、Oracle或DB2,因为我们要编写的是一个通用的工具,可以用于任何数据库表。我是以Pointbase中的一张名为customer_tbl的表为例子的。
JDBC结果集的结构
关系型数表现为一张二维表,有行和列。JDBC结果集就是以表格的形式工作的。结果集对象通过迭代器(Iterate)来遍例表中的数据,并且访问行中的某列数数。下图展现的是customer_tbl表中的数据形式。
为了篇写能将结果集转换为XML的工具,我们需要理解结果集(ResultSet)中都有什么,ResultSetMetaData对象可以告诉我们结果集中某行中各各列的列名和类型。
Document Object Model (DOM)的结构
一个XML文档是一个树型型结构,其子结点包含其它子结点、属性或数据。所以它非常适合存储结果集(ResultSet)中的行和列。下图展示了将上面展示的集果集转换成XML的样子。在树型结构的叶字节点是数据结点,它包含了一行或多行。每一行包含了各列所对应的值。
DOM API 提供了XML文档对象一系列操作方法,它用于创建、读取、修改和删除XML树型结构中结点对象(elements)。我们可以利用DOM提供的方法创建一个新XML文档并且向其中增加结点(elements).标准JAXP (Java API for XML Processing) 和DOM API,它只是一个标准,提供了接口的定义,它的实现很多,在这个列子中我用的是Apache Xerxes实现,你可以用任何一种实现。
将结果集转换为XML
如果我们已用JDBC ResultSet和XML documents基本知识,我们就可以书写我们第一个例子,我们给我们这个类取名为JDBCUtil。
public class JDBCUtil
{
我们首先创建一个方法将JDBC ResultSet转换为DOM,下面是方法声名:
public static Document toDocument(ResultSet rs)
throws ParserConfigurationException, SQLException
{
一个JDBC结果集作为唯一的参数传入,并返回一个XML DOM 或者Document
首先我们利用JAXP API来创建一个Document 对象:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();
Next, the Results element of the document is created.
下一步,创建Document中的element对象。Element中数据与结果集中一行对应。
Element results = doc.createElement("Results");
doc.appendChild(results);
我们取原数据从集果集中,以便获得在一行中有多少列和列名都是什么:
ResultSetMetaData rsmd = rs.getMetaData();
int colCount = rsmd.getColumnCount();
现在,我们遍例结果集,进入循环:
while (rs.next())
{
Element row = doc.createElement("Row");
results.appendChild(row);
创建一行,并把这插入父结点中。
下一步,我们遍历一行中的所有列,我们可以从原数据中获得一共有多少列,ResultSetMetaData.getColumnName()告诉我们每列的名字都是什么,用ResultSet.getObject()方法获得列所对应该的值。下面代码创建了一个叶子结点,代表了结果集中的一行。
for (int i = 1; i <= colCount; i++)
{
String columnName = rsmd.getColumnName(i);
Object value = rs.getObject(i);
Element node = doc.createElement(columnName);
node.appendChild(doc.createTextNode(value.toString()));
row.appendChild(node);
}
现在,我们可以创将创建的XML document返回:
return doc;
}
下面是完整的源代码:
public static Document toDocument(ResultSet rs)
throws ParserConfigurationException, SQLException
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();
Element results = doc.createElement("Results");
doc.appendChild(results);
ResultSetMetaData rsmd = rs.getMetaData();
int colCount = rsmd.getColumnCount();
while (rs.next())
{
Element row = doc.createElement("Row");
results.appendChild(row);
for (int i = 1; i <= colCount; i++)
{
String columnName = rsmd.getColumnName(i);
Object value = rs.getObject(i);
Element node = doc.createElement(columnName);
node.appendChild(doc.createTextNode(value.toString()));
row.appendChild(node);
}
}
return doc;
}
客户端例程
为了测试我们的程序,我们需要一个客户端例程。我将创建一个简单的类CustomerDAO,DAO是J2EE数据访问模式的。可以用它来封装数据源,当一个CustomerDAO被构建,它就会连接到我们的Pointbase数据库。当CustomerDAO被销毁时它会断开对数据库的连接。它的公用API是getCustomerList()方法,下面是它的实现:
public Document getCustomerList()
{
Document doc = null;
try
{
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * from customer_tbl");
doc = JDBCUtil.toDocument(rs);
rs.close();
stmt.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return doc;
}
这个方法执行了一个简单的查询获得customer表中的所有数据。返回的结果集将利用JDBCUtil.toDocument()转换为XML。
下面是一个简单的测试方法用来测试CustomerDAO和JDBCUtil对象。
public static void main(String argv[]) throws Exception
{
CustomerDAO dao = new CustomerDAO();
Document doc = dao.getCustomerList();
System.out.println(JDBCUtil.serialize(doc));
}
我们简单的构建一个CustomerDAO,并且让它返回一个customer列表作为DOM,JDBCUtil.serialize()是utility类中的另一个方法,用来序列化DOM作为一个字符串。
下面是我们测试的输出:
<?xml version="1.0" encoding="UTF-8">
<Results>
<Row>
<CUSTOMER_NUM>1</CUSTOMER_NUM>
<DISCOUNT_CODE>N</DISCOUNT_CODE>
<ZIP>33015</ZIP>
<NAME>SuperCom</NAME>
<ADDR_LN1>490 Rivera Drive</ADDR_LN1>
<ADDR_LN2>Suite 678</ADDR_LN2>
<CITY>Miami</CITY>
<STATE>FL</STATE>
<PHONE>305-777-4632</PHONE>
<FAX>305-777-4635</FAX>
<EMAIL>supercom@aol.com</EMAIL>
<CREDIT_LIMIT>100000</CREDIT_LIMIT>
<LAST_SALE_DATE>1998-01-02</LAST_SALE_DATE>
<LAST_SALE_TIME>08:00:00</LAST_SALE_TIME>
</Row>
<Row>
<CUSTOMER_NUM>2</CUSTOMER_NUM>
<DISCOUNT_CODE>M</DISCOUNT_CODE>
<ZIP>33055</ZIP>
<NAME>Livingston Enterprises</NAME>
<ADDR_LN1>9754 Main Street</ADDR_LN1>
<ADDR_LN2>P.O. Box 567</ADDR_LN2>
<CITY>Miami</CITY>
<STATE>FL</STATE>
<PHONE>305-456-8888</PHONE>
<FAX>305-456-8889</FAX>
<EMAIL>www.tsoftt.com</EMAIL>
<CREDIT_LIMIT>50000</CREDIT_LIMIT>
<LAST_SALE_DATE>1998-01-02</LAST_SALE_DATE>
<LAST_SALE_TIME>09:00:00</LAST_SALE_TIME>
</Row>
...
</Results>
总结
XML是不同平台应用之间数据交换的标准协议。关系数据库是最常用的持久化数据的方式。怎样建立起不同数据结构之间转换的桥梁呢?你的关系统数据库可能有这个功能,如果是这样,你可以学习利用它,如果不是,我已经展示如何利用JDBC和DOM API来达到这个目地。
posted on 2008-01-03 09:01
V哥 阅读(2217)
评论(1) 编辑 收藏