posts - 2,  comments - 1,  trackbacks - 0
 

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 ResultSetXML 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;
}

客户端例程

为了测试我们的程序,我们需要一个客户端例程。我将创建一个简单的类CustomerDAODAOJ2EE数据访问模式的。可以用它来封装数据源,当一个CustomerDAO被构建,它就会连接到我们的Pointbase数据库。当CustomerDAO被销毁时它会断开对数据库的连接。它的公用APIgetCustomerList()方法,下面是它的实现:

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

下面是一个简单的测试方法用来测试CustomerDAOJDBCUtil对象。

public static void main(String argv[]) throws Exception
{
   CustomerDAO dao = new CustomerDAO();
 
   Document doc    = dao.getCustomerList();
   System.out.println(JDBCUtil.serialize(doc));
 
}

我们简单的构建一个CustomerDAO,并且让它返回一个customer列表作为DOMJDBCUtil.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是不同平台应用之间数据交换的标准协议。关系数据库是最常用的持久化数据的方式。怎样建立起不同数据结构之间转换的桥梁呢?你的关系统数据库可能有这个功能,如果是这样,你可以学习利用它,如果不是,我已经展示如何利用JDBCDOM API来达到这个目地。

posted on 2008-01-03 09:01 V哥 阅读(2207) 评论(1)  编辑  收藏


FeedBack:
# re: 将JDBC结果集转换为XML
2008-04-02 09:24 | adsf
amdocslongshine  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 
<2008年4月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

常用链接

留言簿(2)

文章档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜