Storing XML in Relational Databases (1)

 

Storing XML in Relational Databases (1)

From http://www.xml.com

translating by bjcfr

email:bjcfr@sohu.com

引言

有许多方法可以解决XML数据和关系数据库数据之间进行有效的相互转换的问题,数据库系统供应商如:IBM,微软,ORACLESYBASE等均开发了一些工具来帮助把XML文档转换成关系数据表,以下是几种不同的解决方案:

1.         ORACLE XML SQL UTILITY XML文档的诸多元素模拟成一些嵌套的表,相应的元素利用ORACLE OBJICT 数据类型来模拟。“SQL-TO-XML”的转换是通过数据表(referenced by Object datatype)和嵌套元素的一一对应关系来创建XML文档的。“XML-TO-SQL”的转换则需要对数据模型进行修改(把它从关系型转换为对象型)或者重建原始的XML文档。

2.         IBM DB2 XML 扩展允许把XML 文档作为类似于BLOB(二进制大对名象)的对象进行存储或把它们分解成一系列的表进行存储。后者的转换(known as XML collection)在XML 1.0的语法中被定义。

3.         微软通过扩展SQL-92和引进OPENXML行集来解决这个问题。

4.         SYSBASE ADAPTIVESERVER 引进了JAVA ResultSetXml作为这种双向转换处理的基础。

在本文中,我们为先分析一下这些供应商解决方案的细节,然后我们为试着加答下列问题:

           我们能否重新构造并简 个问题?

           在异构数据库环境下什么才是正确的解决方法?

下面的DTD是本文的所使用的范例:

<!-- Primitive Types -->
 
  
  
  
  
<!ELEMENT CURRENCY1   (#PCDATA)>
<!ATTLIST CURRENCY1    e-dtype    NMTOKEN   #FIXED  "string"
                        e-dsize    NMTOKEN   #FIXED  "3">
 
  
  
<!ELEMENT CURRENCY2   (#PCDATA)>
<!ATTLIST CURRENCY2    e-dtype    NMTOKEN   #FIXED  "string"
                        e-dsize    NMTOKEN   #FIXED  "3">
 
  
  
<!ELEMENT AMOUNT      (#PCDATA)>
<!ATTLIST AMOUNT       e-dtype    NMTOKEN   #FIXED  "decimal">
 
  
  
<!ELEMENT SETTLEMENT  (#PCDATA)>
<!ATTLIST SETTLEMENT   e-dtype    NMTOKEN   #FIXED  "date">
 
  
  
<!ELEMENT BANKCODE    (#PCDATA)>
<!ATTLIST BANKCODE     e-dtype    NMTOKEN   #FIXED  "string">
 
  
  
<!ELEMENT BANKACCT    (#PCDATA)>
<!ATTLIST BANKACCT     e-dtype    NMTOKEN   #FIXED  "string">
 
  
  
<!-- Derived Types -->
 
  
  
<!ELEMENT ACCOUNT  (BANKCODE, BANKACCT)>
 
  
  
<!ELEMENT FXTRADE  (CURRENCY1, CURRENCY2, AMOUNT, SETTLEMENT, ACCOUNT)>
 
  
  
 
  
  
Oracle XML-SQL Utility (XSU)
   
   
SQL到XML的映射
  
  
ORACLE 把一系列的对象引用从数据库转化为XML元素的层次结构。表FXTRADE中的字段ACCOUNT用来作为类型AccountType对象引用的模拟。
  
  
 CREATE TABLE FXTRADE 
   
   
{
   
   
     CURRENCY1      CHAR (3),
   
   
     CURRENCY2      CHAR (3),
   
   
     AMOUNT         NUMERIC (18,2),
   
   
     SETTLEMENT     DATE,
   
   
     ACCOUNT        AccountType // object reference
   
   
}
   
   
 
   
   
CREATE TYPE AccountType as OBJECT
   
   
{  
   
   
     BANKCODE       VARCHAR (100),
   
   
     BANKACCT       VARCHAR (100) 
   
   
}
   
   
 
   
   
下面是从给定的对象-关系模型利用语句“SELECT * FROM FXTRADE”产生的相对应的XML文档:
   
   
<?xml version="1.0"?>
  
  
<ROWSET>
  
  
     <ROW num="1"> 
  
  
        <CURRENCY1>GBP</CURRENCY1>
  
  
        <CURRENCY2>JPY</CURRENCY2>
  
  
        <AMOUNT>10000</AMOUNT>
  
  
        <SETTLEMENT>20010325</SETTLEMENT>
  
  
        <ACCOUNT>
  
  
   <BANKCODE>812</BANKCODE>
  
  
   <BANKACCT>00365888</BANKACCT>
  
  
        </ACCOUNT>
  
  
    </ROW>
  
  
    <!-- additional rows ... -->
  
  
 </ROWSET>
  
  
 
  
  
从数据库中提取XML
   
   
下面的例子取自于ORACLE’s XSU 文档,把相应的SQL语句进行的替换并使用ORACLE的纯JAVA JDBC 瘦驱动程序。
   
   
首先,创建一个OracleXMLQuery的实例,然后执行一个查询,结果就是上面所提及的XML文档。相似地,XML文档也可以从DOM中被抽取,在这种情况下,应使用qry.getXMLDOM()而不是getXMLString().
   
   
import oracle.jdbc.driver.*;
  
  
import oracle.xml.sql.query.OracleXMLQuery;
  
  
import java.lang.*;
  
  
import java.sql.*;
  
  
 
  
  
// class to test XML document generation as String
  
  
class testXMLSQL {
  
  
 
  
  
   public static void main(String[] args)
  
  
   {
  
  
     try {
  
  
      // Create the connection
  
  
      Connection conn  = getConnection("scott","tiger");
  
  
 
  
  
      // Create the query class
  
  
      OracleXMLQuery qry = new OracleXMLQuery(conn,
  
  
         "SELECT  * FROM FXTRADE");
  
  
 
  
  
      // Get the XML string
  
  
      String str = qry.getXMLString();
  
  
 
  
  
      // Print the XML output
  
  
      System.out.println("The XML output is:/n"+str);
  
  
 
  
  
      // Always close the query to get rid of any resources..
  
  
      qry.close();
  
  
     } catch(SQLException e) {
  
  
      System.out.println(e.toString());
  
  
     }
  
  
   }
  
  
 
  
  
   // Get the connection given the user name and password.!
  
  
   private static Connection getConnection(String username,
  
  
        String password)
  
  
        throws SQLException
  
  
   {
  
  
      // register the JDBC driver..
  
  
       DriverManager.registerDriver(new 
  
  
          oracle.jdbc.driver.OracleDriver());
  
  
 
  
  
      // Create the connection using the OCI8 driver
  
  
       Connection conn =
  
  
        DriverManager.getConnection(
  
  
           "jdbc:oracle:thin:@dlsun489:1521:ORCL",
  
  
           username,password);
  
  
 
  
  
      return conn;
  
  
   }
  
  
}
  
  
 
  
  
Storing XML in the database
   
   
在这个例子中,用OracleXMLSave来把我们的XML文档存储为一个对象-关系模型insertXML方法用于插入数据。
   
   
import java.sql.*;
  
  
import oracle.xml.sql.dml.OracleXMLSave;
  
  
public class testXMLInsert
  
  
{
  
  
   public static void main(String args[])
  
  
             throws SQLException
  
  
  {
  
  
    Connection conn = getConnection("scott","tiger");
  
  
    OracleXMLSave sav = new OracleXMLSave(conn, "scott. FXTRADE");
  
  
  // Assume that the user passes in this document as 0-arg
  
  
      sav.insertXML(args[0]);
  
  
      sav.close();
  
  
   }
  
  
 
  
  
  ...
  
  
}
  
  
 
  
  
如果XML和数据库中的关系对象模型是同步的,但是如果不同步呢?这种情况下,通常有两种选择:
   
   
1.      调整关系对象模型,通过创建一个可更改的关系对象视图和完成多表的修改。
   
   
2.      可以把XML文档分解成一系列的简单的子文档。我们可以利用XSLT来过完成这个分解过程。
   
   
XSU不允许存储属性值,建议先把属性转换成元素再作处理。
  
  
Oracle XSU总结
   
   
一个XML到SQL的映射可以被一个关系对象模型进行模拟,其创建规则如下:
   
   
每一个嵌套的XML元素被映射为一个适当的对象引用。映射的规则已经内嵌在数据库模型上了。
   
   
相关的JAVA API包括OracleXMLQuery和 OracleXMLSave 两个类。(未待续完)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值