﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-hengheng123456789-文章分类-XML</title><link>http://www.blogjava.net/hengheng123456789/category/14829.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 17:18:23 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 17:18:23 GMT</pubDate><ttl>60</ttl><item><title>使用Java和XML-DBMS将数据库桥接到XML</title><link>http://www.blogjava.net/hengheng123456789/articles/67546.html</link><dc:creator>哼哼</dc:creator><author>哼哼</author><pubDate>Mon, 04 Sep 2006 03:40:00 GMT</pubDate><guid>http://www.blogjava.net/hengheng123456789/articles/67546.html</guid><wfw:comment>http://www.blogjava.net/hengheng123456789/comments/67546.html</wfw:comment><comments>http://www.blogjava.net/hengheng123456789/articles/67546.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hengheng123456789/comments/commentRss/67546.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hengheng123456789/services/trackbacks/67546.html</trackback:ping><description><![CDATA[
		<p>
				<strong>编写映射文件</strong>
		</p>
		<p>映射文件是一个特殊的XML文件，用户在其中指定XML元素、属性（attributes）以及PCDATA如何映射到数据库的表与列。<a href="http://builder.com.com/5110-6370-5054855.html">清单A</a>就是这个XML示例的映射文件，<a href="http://builder.com.com/5110-6370-5054856.html">清单B</a>是
数据库的一个SQL架构。在清单A中，Options元素包含系统特有的一些参数。在这例子中，你要设置相应的格式，以实现DATE类型的数据库字段与
XML数据的相互转换。注意，Pattern属性必须遵循java.text.SimpleDateFormat模式规范。</p>
		<p>
				<a href="http://builder.com.com/5110-6370-5054855.html">清单A</a>:</p>
		<table border="0" cellpadding="0" width="100%">
				<tbody>
						<tr>
								<td class="subhead1">Listing A</td>
						</tr>
						<tr bgcolor="#ff0000">
								<td height="1">
										<img src="http://builder.com.com/i/tr/spacer.gif" height="1" width="1" />
								</td>
						</tr>
						<tr>
								<td height="5">
										<img src="http://builder.com.com/i/tr/spacer.gif" height="5" width="1" />
								</td>
						</tr>
						<tr>
								<td>&lt;?xml version='1.0' ?&gt;<br /><br />&lt;XMLToDBMS Version="2.0" xmlns="http://www.xmlmiddleware.org/xmldbms/v2"&gt;<br /><br />&lt;Options&gt;<br /><br />&lt;SimpleDateFormat Pattern="yyyy-MM-dd" DefaultForTypes="DATE" /&gt;<br /><br />&lt;/Options&gt;<br /><br />&lt;Databases&gt;<br /><br />&lt;Database Name="Default"&gt;<br /><br />&lt;Catalog&gt;<br /><br />&lt;Schema&gt;<br /><br />&lt;Table Name="users"&gt;<br /><br />&lt;Column Name="user_id" DataType="VARCHAR" Length="24" Nullable="No"/&gt;<br /><br />&lt;Column Name="company" DataType="VARCHAR" Length="255" Nullable="No"/&gt;<br /><br />&lt;PrimaryKeyKeyGenerator="UID"&gt;<br /><br />&lt;UseColumn Name="user_id"/&gt;<br /><br />&lt;/PrimaryKey&gt;<br /><br />&lt;/Table&gt;<br /><br />&lt;Table Name="orders"&gt;<br /><br />&lt;Column Name="order_id" DataType="VARCHAR" Length="24" Nullable="No"/&gt;<br /><br />&lt;Column Name="user_id" DataType="VARCHAR" Length="24" Nullable="No"/&gt;<br /><br />&lt;Column Name="posted_at" DataType="DATE" Nullable="No"/&gt;<br /><br />&lt;Column Name="type" DataType="INTEGER" Nullable="Yes"/&gt;<br /><br />&lt;ForeignKey Name="order_to_user_FK"&gt;<br /><br />&lt;UseTable Name="users" /&gt;<br /><br />&lt;UseUniqueKey Name="PrimaryKey" /&gt;<br /><br />&lt;UseColumn Name="user_id"/&gt;<br /><br />&lt;/ForeignKey&gt;<br /><br />&lt;PrimaryKeyKeyGenerator="UID"&gt;<br /><br />&lt;UseColumn Name="order_id"/&gt;<br /><br />&lt;/PrimaryKey&gt;<br /><br />&lt;/Table&gt;<br /><br />&lt;Table Name="cargos"&gt;<br /><br />&lt;Column Name="cargo_id" DataType="VARCHAR" Length="24" Nullable="No"/&gt;<br /><br />&lt;Column Name="order_id" DataType="VARCHAR" Length="24" Nullable="No"/&gt;<br /><br />&lt;Column Name="title" DataType="VARCHAR" Length="255" Nullable="Yes"/&gt;<br /><br />&lt;Column Name="code" DataType="VARCHAR" Length="255" Nullable="Yes"/&gt;<br /><br />&lt;Column Name="quantity" DataType="INTEGER" Nullable="Yes"/&gt;<br /><br />&lt;Column Name="weight" DataType="INTEGER" Nullable="Yes"/&gt;<br /><br />&lt;Column Name="danger" DataType="VARCHAR" Length="255" Nullable="Yes"/&gt;<br /><br />&lt;PrimaryKeyKeyGenerator="UID"&gt;<br /><br />&lt;UseColumn Name="cargo_id"/&gt;<br /><br />&lt;/PrimaryKey&gt;<br /><br />&lt;ForeignKey Name="cargo_to_order_FK"&gt;<br /><br />&lt;UseTable Name="orders" /&gt;<br /><br />&lt;UseUniqueKey Name="PrimaryKey" /&gt;<br /><br />&lt;UseColumn Name="order_id"/&gt;<br /><br />&lt;/ForeignKey&gt;<br /><br />&lt;/Table&gt;<br /><br />&lt;/Schema&gt;<br /><br />&lt;/Catalog&gt;<br /><br />&lt;/Database&gt;<br /><br />&lt;/Databases&gt;<br /><br />&lt;Maps&gt;<br /><br />&lt;ClassMap&gt;<br /><br />&lt;ElementType Name="order"/&gt;<br /><br />&lt;ToClassTable Name="orders"/&gt;<br /><br />&lt;PropertyMap&gt;<br /><br />&lt;ElementType Name="order_id"/&gt;<br /><br />&lt;ToColumn Name="order_id"/&gt;<br /><br />&lt;/PropertyMap&gt;<br /><br />&lt;PropertyMap&gt;<br /><br />&lt;ElementType Name="user_id"/&gt;<br /><br />&lt;ToColumn Name="user_id"/&gt;<br /><br />&lt;/PropertyMap&gt;<br /><br />&lt;PropertyMap&gt;<br /><br />&lt;ElementType Name="posted_at"/&gt;<br /><br />&lt;ToColumn Name="posted_at"/&gt;<br /><br />&lt;/PropertyMap&gt;<br /><br />&lt;PropertyMap&gt;<br /><br />&lt;ElementType Name="type"/&gt;<br /><br />&lt;ToColumn Name="type"/&gt;<br /><br />&lt;/PropertyMap&gt;<br /><br />&lt;RelatedClassKeyInParentTable="Unique"&gt;<br /><br />&lt;ElementType Name="cargo"/&gt;<br /><br />&lt;UseUniqueKey Name="PrimaryKey"/&gt;<br /><br />&lt;UseForeignKey Name="cargo_to_order_FK"/&gt;<br /><br />&lt;/RelatedClass&gt;<br /><br />&lt;/ClassMap&gt;<br /><br />&lt;ClassMap&gt;<br /><br />&lt;ElementType Name="cargo"/&gt;<br /><br />&lt;ToClassTable Name="cargos"/&gt;<br /><br />&lt;PropertyMap&gt;<br /><br />&lt;ElementType Name="cargo_id"/&gt;<br /><br />&lt;ToColumn Name="cargo_id"/&gt;<br /><br />&lt;/PropertyMap&gt;<br /><br />&lt;PropertyMap&gt;<br /><br />&lt;ElementType Name="order_id"/&gt;<br /><br />&lt;ToColumn Name="order_id"/&gt;<br /><br />&lt;/PropertyMap&gt;<br /><br />&lt;PropertyMap&gt;<br /><br />&lt;ElementType Name="title"/&gt;<br /><br />&lt;ToColumn Name="title"/&gt;<br /><br />&lt;/PropertyMap&gt;<br /><br />&lt;PropertyMap&gt;<br /><br />&lt;ElementType Name="code"/&gt;<br /><br />&lt;ToColumn Name="code"/&gt;<br /><br />&lt;/PropertyMap&gt;<br /><br />&lt;PropertyMap&gt;<br /><br />&lt;ElementType Name="quantity"/&gt;<br /><br />&lt;ToColumn Name="quantity"/&gt;<br /><br />&lt;/PropertyMap&gt;<br /><br />&lt;PropertyMap&gt;<br /><br />&lt;ElementType Name="weight"/&gt;<br /><br />&lt;ToColumn Name="weight"/&gt;<br /><br />&lt;/PropertyMap&gt;<br /><br />&lt;PropertyMap&gt;<br /><br />&lt;ElementType Name="danger"/&gt;<br /><br />&lt;ToColumn Name="danger"/&gt;<br /><br />&lt;/PropertyMap&gt;<br /><br />&lt;/ClassMap&gt;<br /><br />&lt;/Maps&gt;<br /><br />&lt;/XMLToDBMS&gt;<br /></td>
						</tr>
				</tbody>
		</table>
		<a href="http://builder.com.com/5110-6370-5054856.html">清单B</a>:<br /><table border="0" cellpadding="0" width="100%"><tbody><tr><td class="subhead1">Listing B</td></tr><tr bgcolor="#ff0000"><td height="1"><img src="http://builder.com.com/i/tr/spacer.gif" height="1" width="1" /></td></tr><tr><td height="5"><img src="http://builder.com.com/i/tr/spacer.gif" height="5" width="1" /></td></tr><tr><td><pre>CREATE TABLE XMLDBMSKey (</pre><pre>HighKeyint(11)</pre><pre>);</pre><pre>CREATE TABLE orders (</pre><pre>order_idvarchar(24) DEFAULT '' NOT NULL,</pre><pre>user_idvarchar(24) DEFAULT '' NOT NULL,</pre><pre>posted_atdate,</pre><pre>type integer,</pre><pre>PRIMARY KEY (order_id)</pre><pre>);</pre><pre>CREATE TABLE cargos (</pre><pre>cargo_idvarchar(24) DEFAULT '' NOT NULL,</pre><pre>order_idvarchar(24) DEFAULT '' NOT NULL,</pre><pre>title varchar(255),</pre><pre>code varchar(255),</pre><pre>quantity integer,</pre><pre>weight integer,</pre><pre>danger varchar(255),</pre><pre>PRIMARY KEY (cargo_id)</pre><pre>);</pre></td></tr></tbody></table><br /><br /><p>清单A的Databases元素包含数据库的一个关系架构。该构架确保XML-DBMS能正确地映射数据并编译映射文件（如果要在多个映射文件中使用相同的数据库架构，最好的办法就是在每个文件中将架构作为一个XML外部实体来包容，不必每次都进行重写）。</p><p>数据库名称“Default”意味着数据库必须在JDBC连接URL中显式地指定。必须在每个表中提供主键信息，而且每个键都必须存在于数据库中。否则，编译器可能报告一个映射异常。</p><p>在KeyGenerator中，你需要提供主键生成器的名称，同时必须用一个独立的Java类来实现这个生成器。KeyGenerator是Java接口的一个实现，每次执行一个INSERT操作时，它都会生成一个惟一的键值。也可使用一个简单的、现成的生成器。</p><p>图B的XMLDBMSKey表包含了由KeyGenerator使用的值。UseColumn元素指向一个充当主键的元素，并告诉程序在哪里写生成
的键值。除非Name属性明确指定了一个名称，否则主键会隐式地采用PrimaryKey这一默认名称。主键可能同时使用了多列，
KeyGenerator的实现必须知道它应该生成多少个键。</p><p>清单A的ForeignKey元素用于描述元素类之间的主键–外键关系。</p><p>在映射文件中，最重要的一部分就是Maps小节。元素类型及其内容通常被视为一个类，并映射到一个表。这是通过一个ClassMap元素及其子元素
来完成的。子元素包括ElementType，其中含有要映射的元素的名称；以及ToClassTable，它指定元素要映射到哪个表。</p><p>PropertyMap元素能控制“简单”（子节点中的PCDATA）元素或属性（attribute）映射——虽然在这个例子中，应用程序映射的
只是元素。RelatedClass元素允许我们在此封装另一个元素类，但那个类必须在另一个ClassMap元素中得到定义。</p><p>映射文档编译成XMLDBMap Java对象，最终的结果会传给DBMSToDOM、DOMToDBMS或者DBMSDelete对象。这些特殊对象负责与选择、插入、更新或删除数据有关的全部工作。</p><br /><p><strong>编写过滤器和动作文件</strong></p><p>过滤器文档由一系列过滤器构成，这些过滤器应用于数据库中的值。这样一来，过滤器就能过滤由SELECT操作检索的行或者由DELETE操作删除的
行。过滤器语言位于映射语言的顶端。换言之，过滤器文档允许你指定数据的检索条件，而映射语言提供结构化信息（也就是联接–join）。你可认为映射语言
和过滤器语言合并在一起，共同为数据库提供了一套简单的查询语言，它确保结果以XML的形式返回。过滤器文档要编译成FilterSet
Java对象，最终的对象会传给DBMSToDOM或者DBMSDelete对象。</p><p>动作文档由一系列动作构成，这些动作要应用于XML文档中的值。你需要为作为类来映射的元素类型指定相应的动作。这些动作会转换为对行的插入、更新
及删除操作。在一个动作文档中，如果已经规定特定的行需要插入或更新，就不能再规定那些行需要删除；反之亦然。如果一个动作文档规定某些行需要插入或更
新，就会由DOMToDBMS对象来使用那些文档。相反，如果规定某些行需要删除，则会由DBMSDelete对象来使用。</p><p>Listing C</p><p class="code">＜?xmlversion='1.0' ?＞<br />＜Actions Version="2.0" xmlns="http://www.xmlmiddleware.org/xmldbms/actions/v2"＞<br />＜DefaultAction＞<br />＜None /＞<br />＜/DefaultAction＞<br />＜Action＞<br />＜ElementType Name="order" /＞<br />＜UpdateOrInsert /＞<br />＜/Action＞<br />＜Action＞<br />＜ElementType Name="cargo" /＞<br />＜UpdateOrInsert /＞<br />＜/Action＞<br />＜/Actions＞</p><p>清单C演示了插入/更新动作。这段代码会使用一个已知的主键（如果存在的话）来更新一个行，或者生成一个新的主键（如果不存在的话）。实际上，你需要为两个类（order和cargo）插入元素，因为cargo元素嵌套在order元素中。</p><p>Listing D</p><p class="code">＜?xmlversion='1.0' ?＞<br />＜FilterSet Version="2.0" xmlns="http://www.xmlmiddleware.org/xmldbms/filters/v2"＞<br />＜Options＞<br />＜Wrapper Name="orders" /＞<br />＜/Options＞<br />＜Filters＞<br />＜Filter＞<br />＜RootFilter＞<br />＜Table Name="orders" /＞<br />＜Where Condition=" user_id = 'UID745632' "/＞<br />＜/RootFilter＞<br />＜/Filter＞<br />＜/Filters＞<br />＜/FilterSet＞</p><p>选择或删除数据时，需要使用包含在清单D中的过滤器文件。Options元素包含一个特殊的Wrapper元素，它用于包装查询结果。如果会从数据
库中检索多个元素，就需要使用Wrapper元素。在这种情况下，生成的是含有多个根元素的XML结构，现行的许多标准都不支持它。</p><p>RootFilterelements用于指定从根表检索到的值。</p><br /><p><strong>编写Java代码</strong></p><p>现在，我们已准备好编写自己的应用程序，它将在一个关系数据库中存储和检索DOM文档。清单E包含了示范性的Java代码，它有必要进一步说明。</p><p>Listing E</p><p class="code">package test.xmldbms;<br />importorg.xmlmiddleware.db.*;<br />import org.xmlmiddleware.utils.XMLMiddlewareException;<br />importorg.xmlmiddleware.xmldbms.*;<br />importorg.xmlmiddleware.xmldbms.tools.*;<br />importorg.xmlmiddleware.xmldbms.actions.*;<br />importorg.xmlmiddleware.xmldbms.datahandlers.*;<br />importorg.xmlmiddleware.xmldbms.filters.*;<br />importorg.xmlmiddleware.xmldbms.keygenerators.*;<br />importorg.xmlmiddleware.xmldbms.maps.*;<br />importorg.xmlmiddleware.xmlutils.*;<br />importorg.xml.sax.*;<br />import org.w3c.dom.*;<br />importjava.io.*;<br />importjava.util.*;<br />public class XMLToDBMSAndViceVersa<br />{<br />// Service objects<br />private DOMToDBMSdomToDBMS = null;<br />private DBMSToDOMdbmsToDOM = null;<br />private DBMSDeletedbmsDelete = null;<br />// Credentials for connecting to database<br />private static String JDBC_DRIVER = "org.gjt.mm.mysql.Driver";<br />private static String JDBC_URL = "jdbc:mysql://localhost/dbname";<br />private static String JDBC_DBNAME = "dbname";<br />private static String JDBC_USER = "dbuser";<br />private static String JDBC_PASSWORD = "dbpassword";<br />// Some file names<br />private static String mapFilename = "Listing-A.map";<br />private static String actionFilename = "Listing-C.act";<br />private static String filterFilename = "Listing-D.act";<br />// Datahandler class<br />private static String GENERICHANDLER = "org.xmlmiddleware.xmldbms.datahandlers.GenericHandler";<br />// Key generation class<br />private static String KEYGENERATOR = "org.xmlmiddleware.xmldbms.keygenerators.KeyGenerator";<br />// Parser utils class; XML-DBMS does not yet support JAXP, so such operations as XML parsing and serializing<br />// needs to be a little customized for each parser. this is the class for supporting Xerces parser.<br />private static String PARSERUTILSCLASS = "org.xmlmiddleware.xmlutils.external.ParserUtilsXerces";<br />private static boolean VALIDATING_PARSER = false;<br />public static void main(String [] args) {<br />// Tell the JVM to run finalizers on exit. This is necessary to ensure<br />// that database connections are properly closed.<br />System.runFinalizersOnExit(true);<br />// Creating parser utilities<br />ParserUtilsutils = (ParserUtils)Class.forName(PARSERUTILSCLASS).newInstance();<br />// Creating a data source and data handler.<br />DataSourcedataSource = new JDBC1DataSource(JDBC_DRIVER, JDBC_URL);<br />dataHandler = (DataHandler)Class.forName(GENERICHANDLER).newInstance();<br />dataHandler.initialize(dataSource, JDBC_USER, JDBC_PASSWORD);<br />// Compiling and instantiating a Map object<br />MapCompiler compiler = new MapCompiler(utils.getXMLReader(VALIDATING_PARSER));<br />XMLDBMSMap map = compiler.compile(new InputSource(new FileReader(mapFilename)));<br />// Create an object containing information needed to transfer data<br />TransferInfotransferInfo = new TransferInfo(map);<br />transferInfo.addDataHandler(JDBC_DBNAME, dataHandler);<br />// Compiling and instantiating an Action object<br />ActionCompiler compiler = new ActionCompiler(utils.getXMLReader(VALIDATING_PARSE));<br />Actions actions = compiler.compile(map, new InputSource(new FileReader(actionFilename)));<br />// Creating and configuring service object<br />domToDBMS = new DOMToDBMS();<br />domToDBMS.setCommitMode(DataHandler.COMMIT_AFTERSTATEMENT);<br />domToDBMS.stopOnException(true);<br />domToDBMS.setFilterSetReturned(false);<br />KeyGeneratorkeyGen = (KeyGenerator)Class.forName(KEYGENERATOR).newInstance();<br />domToDBMS.addKeyGenerator("UID", keyGen); // Adding used in Listing-A key generator named UID<br />// Getting our XML document into DOM document<br />Document doc = utils.openDocument(new InputSource(new StringReader(xmlString)),VALIDATING_PARSER);<br />// Ooops... and our XML file is already in the database!<br />domToDBMS.storeDocument(transferInfo, doc, actions);<br />// Creating FilterSet object for retrieving data<br />FilterCompiler compiler = new FilterCompiler(utils.getXMLReader(validate));<br />FilterSetfilterSet = compiler.compile(map, new InputSource(new FileReader(filterFilename)));<br />// Creating and configuring another service object<br />dbmsToDOM = new DBMSToDOM(utils);<br />dbmsToDOM.setDTDInfo(null, null);<br />Hashtableparams = new Hashtable();<br />// And now we are getting a DOM document from database<br />doc = dbmsToDOM.retrieveDocument(transferInfo, filterSet, params, null);<br />}<br />}</p><p>首先，你必须实例化一个数据源和一个数据处理程序。JDBC1DataSource类是JDBC 2.0
DataSource的一个实现，它用于一个遵循JDBC1标准的驱动程序，而且提供了对连接池的支持。Datahandler是用于对数据库访问进行抽
象的一个接口。你还要指示JVM在退出时运行终结器（finalizers），这是用System.runFinalizersOnExit(true)
来实现的。终结器必须运行，否则无法保证数据库连接正确关闭。ParserUtils是实现了解析器特有方法的一个类的接口。之所以需要它，是因为XML
解析和序列化操作需要针对每一个解析器进行少许定制。</p><p>你必须编译和实例化一个Map对象、Actions对象以及FilterSet对象，它们全都会在文档转换过程中使用。为此，你需要使用由
MapCompiler、ActionCompiler和FilterCompiler等对象提供的相应的方法。TransferInfo对象包含在
XML文档和数据库之间传输数据所需的信息。它封装了根据一个特定的映射，在XML文档和数据库之间传输数据所需的映射元数据以及DataHandler
对象。它为每个数据库都包含单独一个XMLDBMSMap对象和一个DataHandler对象。你还必须创建一个KeyGenerator实现对象，以
便在插入新对象时生成主键。键用于联接不同的表（从类表到类表，或者从类表到属性表），还用于从根表（root tables）检索数据。</p><p>最后，你可创建一个DOMToDBMS对象，以便将数据从一个DOM树传输到数据库。采取类似的方式，还可创建一个DBMSToDOM对象，以便将关系数据传回DOM。</p><p><strong>总结</strong></p><p>本文证明使用XML-DBMS来存储XML数据其实并不难。如果你已经建立了一个关系数据库基础结构，或者希望建立一个独立于数据库厂商的基础结
构，就推荐采取这种方式。由于XML-DBMS不要求任何特定的数据库，所以你的数据库只需理解标准SQL，而且有一个JDBC驱动程序（或者具有桥接机
制的一个
ODBC驱动程序）就可以了。如果你的应用程序需要搜索或者合并来自不同类型的数据源的信息，就适合使用这个框架，因为关系数据库架构很容易通过XML
DTD和XML架构来建立，另外还有大量工具可将DTD和架构转换成映射文件。另外，还可用它生成由数据驱动的应用程序，比如一个CMS或者CRM系统。
XML-DBMS是从XML到DBMS的中间件产品的一个典范，能有效地整合支持和不支持XML的系统。</p><p><br /></p><p><br /></p><img src ="http://www.blogjava.net/hengheng123456789/aggbug/67546.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hengheng123456789/" target="_blank">哼哼</a> 2006-09-04 11:40 <a href="http://www.blogjava.net/hengheng123456789/articles/67546.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>