Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Using the SQLXML data type

The Java data type for database type XML

Deepak Vohra (dvohra09@yahoo.com), Consultant, Independent
Deepak Vohra is a Web developer, an independent consultant, a Sun certified Java Programmer, and a Sun certified Web Component Developer. Deepak has published in ONJava.com, java.net, XML Journal, and Oracle Magazine.

Summary:  If you're a Java™ 2 Enterprise Edition (J2EE) developer, you'll want to preview the SQLXML technology. Check out procedures to create an XML document, store an XML document in a relational database, retrieve an XML document from a database, and navigate an XML document with the SQLXML Java data type.

Date:  07 Apr 2008 (Published 09 May 2006)
Level:  Intermediate
Also available in:   Chinese  Russian  Japanese

Activity:  14120 views
Comments:  

Overview

J2EE developers are commonly required to store an XML document in a relational database and retrieve an XML document from a database to obtain element and attribute values. Currently, only vendor-specific technologies and data types are available to store an XML document in a relational database. For example, IBM DB2 Universal Database™ (UDB) provides the DB2 XML Extender to store an XML document and XML user-defined types (UDTs). A standard data type for XML type columns and a Java data type corresponding to XML type columns would facilitate the storage and retrieval of XML documents in a relational database. The SQL:2003 standard supports such a data type: the new XML data type, for storing XML documents in a relational database. With the XML data type, you can store an XML document in a database table column similar to the other data types. DB2 database Version 9.x supports the XML data type. The Java Database Connectivity (JDBC) 4.0 specification supports the SQL:2003 standard. IBM Data Server Driver for JDBC and SQLJ Version 4.0 supports JDBC 4.0 specification.

Preliminary setup

Before you begin, make sure you have the necessary components to follow along. SQLXML is a JDBC 4.0 data type. Because the SQLXML data type is implemented in the Java Development Kit (JDK) 6.0, you'll need to install it. Another requirement to create an SQLXML type object in a relational database that supports the XML data type. DB2 database Version 9.x supports the XML data type. To run the sample application included with this article, SQLXMLDB.java, install a DB2 9.x database and create the sample DB2 database instance, Sample. JDK 6.0, DB2 9, and SQLXMLDB.java are available from Resources and Download, respectively.

You'll also require a JDBC 4.0 driver. IBM Data Server Driver for JDBC and SQLJ Version 4.0 is a JDBC 4.0 driver. To run SQLXMLDB.java with IBM Data Server Driver for JDBC and SQLJ Version 4.0, add JAR files db2jcc4.jar and db2jcc_license_cu.jar to the Classpath.

Getting started

The SQLXML Java data type lets you map an XML type database column to a Java data type. In the JDBC 4.0 specification, the java.sql.Connection interface can create an SQLXML object which initially does not have any data, but you can add data with the setString(), setBinaryStream(), setCharacterStream(), or setResult() methods. An SQLXML object is retrievable from a ResultSet or a CallableStatement object with the getSQLXML(int columnIndex) method or the getSQLXML(String columnName) method. Retrieve the data in a SQLXML object with one of the getString(), getBinaryStream(), getCharacterStream(), or getSource() methods. You can store an SQLXML object in a database table column of type XML similar to any other data type with the setSQLXML(int parameterIndex, SQLXML sqlXML) method of the PreparedStatement interface.

Listing 1 shows an example of an XML document, catalog.xml, which you can create:


Listing 1. Sample XML document, catalog.xml

<catalog title="XML Zone" publisher="IBM developerWorks"> 
 <journal date="Jan 2006"> 
  <article>
   <title>Managing XML data: Tag URIs</title>
   <author>Elliotte Harold</author>
  </article>
  <article> 
   <title>Practical data binding: XPath as data binding tool, Part 2</title>
   <author>Brett McLaughlin</author>
  </article>
 </journal>
</catalog>


Selecting a database

A relational database is required to support the XML data type to store an XML document. Not all databases support the XML data type. To find out if a database supports it, obtain the database metadata from a Connection object. For example, to test if DB2 9 supports the XML data type, load and register the com.ibm.db2.jcc.DB2Driver JDBC driver, the DB2 JDBC Type 4 driver:

 
Class.forName("com.ibm.db2.jcc.DB2Driver");

Specify the connection URL for DB2 UDB database. The format of DB2 UDB Type 4 driver is jdbc:db2://<server>:<port>/<database>. In the connection URL, <server> is the DB2 UDB server name, <port> is the DB2 database port, and <database> is the DB2 database instance. The connection URL for DB2 UDB database is:

String url = "jdbc:db2://localhost:50000/Sample";

Obtain a Connection with the database with DriverManager static method getConnection():

Connection connection = DriverManager.getConnection(url,
                     "username", "password");

Next, obtain database metadata from the Connection object:

DatabaseMetaData metadata =  connection.getMetaData();

Subsequently, get the data types supported by the database with the getTypeInfo() method:

ResultSet rs = metadata.getTypeInfo();

Iterate over the data type result set and output the TYPE_NAME column:

System.out.println("TYPE_NAME:"+rs.getString("TYPE_NAME"));

If the database supports the XML data type, the XML TYPE_NAME gets output. As the DB2 9 database supports the XML data type, output from running SQLXMLDB.java application includes the XML data type as shown here:

TYPE_NAME: XML

Creating an SQLXML object

This section discusses the procedure to create an SQLXML object. First, import the java.sql package and the javax.xml.stream package. The javax.xml.stream package has the XMLStreamWriter and XMLStreamReader interfaces required to instantiate an SQLXML object and obtain data in an SQLXML object.

import java.sql.*;
import javax.xml.stream.*;

The Java representation of an XML document in a database table column of type XML is SQLXML. To create an XML document to be stored in the XML type column, create an SQLXML object from the Connection object with the createSQLXML() method:

SQLXML sqlXML = connection.createSQLXML();

The SQLXML object created with the createSQLXML() method does not contain any data. The next section shows how to add data to the SQLXML object.

Initializing an SQLXML object

You can initialize an SQLXML object using one of the setString(), setBinaryStream(), setCharacterStream(), or setResult() methods. To initialize an SQLXML object, use the setResult() method and the StAXResult class. Create an XMLStreamWriter object from the StAXResult object with getXMLStreamWriter() method.

StAXResult staxResult = sqlXML.setResult(StAXResult.class);
XMLStreamWriter xmlStreamWriter = staxResult.getXMLStreamWriter();

After you invoke the setResult() method, the SQLXML object becomes non-writable.

Add the start of an XML document with the writeStartDocument(String encoding, String version) method. The encoding specified in the writeStartDocument() method does not set the encoding of the XML document output; the encoding specified only sets the encoding in the XML declaration. The XMLStreamWriter interface also includes the writeStartDocument() method to create an XML document without specifying encoding and version, and the writeStartDocument(String version) method to create an XML document with version:

xmlStreamWriter.writeStartDocument("UTF-8","1.0");

Add the start of the root element, catalog, with the writeStartElement(String localName) method as shown in following code snippet. Use the writeStartElement(String prefix, String localName, String namespaceURI) method to create an element with a namespace and a prefix. Generate an empty element with the writeEmptyElement(String localName) method:

xmlStreamWriter.writeStartElement("catalog");

Add the title attribute with the writeAttribute(String localName, String value) method, as shown in the following code snippet. Similarly, add the publisher attribute. If an attribute has a namespace prefix, use the method writeAttribute(String prefix, String namespaceURI, String localName, String value):

xmlStreamWriter.writeAttribute("title", "XML Zone");
mlStreamWriter.writeAttribute("publisher", "IBM developerWorks");

Similarly, add the journal element and its attribute, date:

xmlStreamWriter.writeStartElement("journal");
xmlStreamWriter.writeAttribute("date", "Jan 2006");

Add an article element and a title element:

xmlStreamWriter.writeStartElement("article");
xmlStreamWriter.writeStartElement("title");

Add text to a title element with the writeCharacters(String text) method, as shown in the following code snippet. Alternatively, add text from a char[] array with the method writeCharacters(char[] text,int start,int len).

xmlStreamWriter.writeCharacters("Managing XML data: Tag URIs");

Ensure that the start element has a corresponding end element tag. Use the writeEndElement() method to add an end element:

xmlStreamWriter.writeEndElement();

The writeEndElement() method does not specify the element local name as the writeStartElement() does. Similarly, add the other elements to create the XML document shown in Listing 1. To complete the XML document, invoke the writeEndDocument() method. Also, close the XMLStreamWriter object:

xmlStreamWriter.writeEndDocument();
xmlStreamWriter.close();

You can also add an XML document to an SQLXML object from an XML string with the setString(String) method of interface SQLXML, as shown in Listing 2.


Listing 2. Adding an XML document to an SQLXML object
sqlXML.setString("<catalog title="DB2 Zone" publisher="IBM developerWorks"> 
 <journal date="Jan 2006"> 
  <article>
   <title>Managing XML data: Tag URIs</title>
   <author>Elliotte Harold</author>
  </article>
  <article> 
   <title>Practical data binding: XPath as data binding tool, Part 2</title>
   <author>Brett McLaughlin</author>
  </article>
 </journal>
</catalog>");

The SQLXML object becomes non-writable after the setString() method is invoked. If the setString(), setBinaryStream(), setCharacterStream(), or setResult() method is invoked on an SQLXML object that has been previously initiated SQLException gets generated. The following section explains how to store the SQLXML object created in a database.

Storing an SQLXML object

The SQLXML Java data type is stored in an XML document just like any other Java data type. First, create a database table with an XML type column. From an SQL command line tool or with the JDBC API, create the database table with an XML type column. To create a database table with JDBC, obtain a Statement object from the Connection object:

Statement stmt = connection.createStatement();

Create a database table, Catalog, for example, with an XML type column:

stmt.executeUpdate("CREATE Table Catalog(CatalogId INTEGER, Catalog XML)");

Store the SQLXML object, created in the previous section, to the database. Create a PreparedStatement object to add values to the database table Catalog. The PreparedStatement consists of an INSERT SQL statement with parameter markers for the values to be added to database:

PreparedStatement statement = 
    connection.prepareStatement("INSERT INTO CATALOG(catalogId, catalog) VALUES(?,?)");

Set the int value with the setInt(int parameterIndex, int value) method and the SQLXML value with the setSQLXML(int parameterIndex, SQLXML value) method of the PreparedStatement interface, as shown below. If you do not close the XMLStreamWriter object prior to invoking the setSQLXML() method, SQLException is thrown.

statement.setInt(1, 1);
statement.setSQLXML(2, sqlXML);

Update the database with the executeUpdate() method:

statement.executeUpdate();

SQLXML objects are valid for at least the duration of the transaction in which the SQLXML objects are created. If you do not use an SQLXML object, release the SQLXML object resources with the free() method:

sqlXML.free();

Updating an SQLXML object

JDK 6.0 also provides updater methods in the ResultSet interface to update SQLXML values. Updater methods updateSQLXML(int columnIndex, SQLXML sqlXML) and updateSQLXML(String columnName, SQLXML sqlXML) revise the SQLXML value in the current row or the insert row of a ResultSet object. For example, to add a new row in a ResultSet object, obtain a Statement object of an updateable ResultSet type:

Statement stmt = connection.createStatement(
                   ResultSet.TYPE_SCROLL_INSENSITIVE,
                   ResultSet.CONCUR_UPDATABLE);

Obtain a ResultSet from the database table Catalog, which has a column of type XML. Move the ResultSet cursor to insert a row. Add the SQLXML column value with the updateSQLXML() method. The updateSQLXML() methods do not update the database. To update the database, invoke the insertRow() method:

ResultSet rs = stmt.executeQuery("SELECT * from Catalog");
rs.moveToInsertRow();
rs.updateSQLXML(2, xmlObject);
rs.insertRow();

Alternatively, to update ResultSet from a current row, in a scrollable ResultSet, move to a ResultSet row with an absolute(int) or relative(int) method. Revise the SQLXML value with one of the updater methods. Update the database with the updateRow() method:

rs.absolute(5);
updateSQLXML("catalog", xmlObject)
rs.updateRow();

If you do not close the XMLStreamWriter object prior to invoking the updater methods, SQLException gets thrown.

Retrieving an SQLXML object from a ResultSet object

Retrieve an XML database data type column value as an SQLXML Java type. Create a PreparedStatement for a SELECT SQL query to obtain a ResultSet from the database table, Catalog, as shown in the following code snippet. The SQL statement has a parameter marker for CatalogId value.

PreparedStatement stmt = 
    connection.prepareStatement("SELECT * FROM  CATALOG WHERE CatalogId=?");

Specify the CatalogId value for which an XML document is to be retrieved:

stmt.setInt(1, 1);

Obtain a result set with the executeQuery() method:

ResultSet rs = stmt.executeQuery();

Use the ResultSet interface method getSQLXML(int columnIndex) or getSQLXML(String columnName) to get the SQLXML object for the XML type Catalog column:

SQLXML sqlXML = rs.getSQLXML("Catalog");

To output the XML document in the SQLXML object, you might use the getString() method of SQLXML interface:

System.out.println(sqlXML.getString());

Accessing an SQLXML object

Retrieve the XML document in a SQLXML object using one of the getBinaryStream(), getCharacterStream(), or getSource() methods. Use the XMLStreamReader interface to read an XML document in an SQLXML object with an event iterator. Create an XMLStreamReader object from the SQLXML object that is to be navigated:

InputStream binaryStream = sqlXML.getBinaryStream();
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader xmlStreamReader = factory.createXMLStreamReader(binaryStream);

The SQLXML object becomes non-readable after the getBinaryStream() method is invoked. The next parse event is obtained with the next() method:

while(xmlStreamReader.hasNext()){
int parseEvent = xmlStreamReader.next();
}

The next() method returns an int value which corresponds to an XMLStreamConstants constant. Table 1 lists the return values of the next() method.


Table 1. Method next() return Value
Parse EventDescription
ATTRIBUTESpecifies an attribute
CDATACData section
CHARACTERSText
NOTATION_DECLARATIONSpecifies a notation declaration
COMMENTXML document comment
PROCESSING_INSTRUCTIONSpecifies a processing instruction
START_DOCUMENTSpecifies a start of document
START_ELEMENTSpecifies the start of an element
END_ELEMENTSpecifies the end of an element
ENTITY_DECLARATIONSpecifies an entity declaration
ENTITY_REFERENCESpecifies an entity reference
NAMESPACESpecifies a namespace declaration
SPACESpecifies an ignorable white space
END_DOCUMENTSpecifies end of document
DTDSpecifies a DTD

If the return value is START_ELEMENT, the parse event indicates an element has been parsed. Use the methods getLocalName(), getPrefix(), getNamespaceURI() to obtain the local name, prefix, and namespace elements:

if(parseEvent==XMLStreamConstants.START_ELEMENT){
System.out.println("Element Local Name: "+xmlStreamReader.getLocalName());
System.out.println("Element Prefix: "+xmlStreamReader.getPrefix());
System.out.println("Element Namespace:"+xmlStreamReader.getNamespaceURI()); 
}

Obtain the attribute count in an element with the getAttributeCount() method. Iterate over the attributes and obtain the attribute local name with the getAttributeLocalName() method, the attribute value with the getAttributeValue() method, the attribute prefix with the getAttributePrefix() method, and the attribute namespace with the getAttributeNamespace() method:

for(int i=0; i<xmlStreamReader.getAttributeCount();i++){

System.out.println("Attribute Prefix:"+xmlStreamReader.getAttributePrefix(i));
System.out.println("Attribute Namespace:"+xmlStreamReader.getAttributeNamespace(i));
System.out.println("Attribute Local Name:"+xmlStreamReader.getAttributeLocalName(i));
System.out.println("Attribute Value:"+xmlStreamReader.getAttributeValue(i));
}

If the parse event is of type CHARACTERS, obtain the text of the parse event with the getText() methods:

if(parseEvent==XMLStreamConstants.CHARACTERS){
    System.out.println("CHARACTERS text: "+xmlStreamReader.getText());
    }

Conclusion

The SQLXML data type provides a database-to-Java mapping facility for database type XML. You can use the SQLXML data type with any database that supports the XML data type, and provides a JDBC 4.0 driver. Vendor-specific XML-to-SQL APIs are not required with SQLXML. The SQLXML API is included in JDK 6.0. DB2 9 supports the XML data type. IBM Data Server Driver for JDBC and SQLJ Version 4.0 is the JDBC 4.0 driver for DB2 9 database.



Download

DescriptionNameSizeDownload method
Sample application SQLXMLDB.javax-sqlxmldb.zip2KB HTTP

Information about download methods


Resources

Learn

Get products and technologies

Discuss

About the author

Deepak Vohra is a Web developer, an independent consultant, a Sun certified Java Programmer, and a Sun certified Web Component Developer. Deepak has published in ONJava.com, java.net, XML Journal, and Oracle Magazine.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=XML, Java technology
ArticleID=110892
ArticleTitle=Using the SQLXML data type
publish-date=04072008
author1-email=dvohra09@yahoo.com
author1-email-cc=dwxed@us.ibm.com

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers