PDA

View Full Version : JDBC/JDOM XML Database Example


hqm
01-21-2003, 07:52 AM
Some people had asked recently about code to convert JDBC queries
into XML.

Here is a very simple example of doing this using manually using JDBC and JDOM. JDOM
is a DOM library for Java that is said to be easier to use than the w3c.org DOM
Java bindings.

JDOM is available from www.jdom.org

This example issues a query "select * from employees" to a database
and then formats the result as an XML document.

For a 'employees' table with columns 'name', 'age', and 'job', and two rows of data, the result might
look like this



<?xml version="1.0" encoding="UTF-8" ?>
<sqldata>
<row>
<name>fred frumble</name>
<age>33</age>
<job>punch press operator</job>
</row>
<row>
<name>freda fertilizer</name>
<age>23</age>
<job>farm hand</job>
</row>
</sqldata>


The example also shows the use of a JDBC connection pool, using a third party library
called jdbcpool.

The code doesn't do any error handling to speak of, it's just to show the
use of JDOM and JDBC together.





/* JDBCTest.java
*
*/

import java.io.*;
import java.text.*;
import java.util.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.jdom.*;
import org.jdom.output.*;
import com.bitmechanic.sql.*;

/**
* Example JDBC to XML conversion, talking to Postgres,
*
* Demonstrates use of JDBC connection pool as well.
* See http://www.bitmechanic.com/projects/jdbcpool/ for connection pool library
*
* @author Henry Minsky
*/

public class JDBCTest extends HttpServlet {

private ConnectionPoolManager pool;
private String alias = "jdbcalias";

public void init(ServletConfig config) throws javax.servlet.ServletException {
super.init(config);
// Setup connection pool
try {
//
// Reap stale connections every 2 minutes
pool = new ConnectionPoolManager(120);

pool.addAlias(alias, // pool name
"org.postgresql.Driver", //driver
"jdbc:postgresql:testdb", //url is jdbc:postgresql:DATABASE_NAME
"postgres", // user
"", // password
20, // maxconn
600, // idletimeout
600); // checkout timeout


} catch (Exception e) {
}
}

public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
response.setContentType("text/xml");
PrintWriter out = response.getWriter();
String query = "SELECT name, age, job FROM employees";
try {

Document doc = new Document();
Element root = new Element("sqldata");
doc.setRootElement(root);

Connection conn = DriverManager.getConnection(ConnectionPoolManager. URL_PREFIX + alias, null, null);
Statement stmt = conn.createStatement();
ResultSet resultset = stmt.executeQuery(query);
//Get the ResultSet information
ResultSetMetaData resultmetadata = resultset.getMetaData();
//Determine the number of columns in the ResultSet
int numCols = resultmetadata.getColumnCount();
while (resultset.next()) {
List elts = new ArrayList();
for (int i=1; i <= numCols; i++) {
//For each column index, determine the column name
String colName = resultmetadata.getColumnName(i);
//Get the column value
String colVal = resultset.getString(i);
//Output the name and value
Element elt = new Element(colName);
elt.setText(colVal);
elts.add(elt);
}
Element row = new Element("row");
row.setChildren(elts);
root.addContent(row);
}

resultset.close();
stmt.close();
conn.close();

XMLOutputter outputter = new XMLOutputter();
try {
outputter.output(doc, out);
}
catch (IOException e) {
out.println(e);
}
} catch (SQLException e) {
out.println(e);
}
}


Assuming that servlet is installed at the URL shown below, (/examples/servlet/JDBCTest)
then the following laszlo program will load the data and display it:


<canvas width="1000" height="800" debug="true">
<!-- setup HTTP datasource -->
<dataset name="xml" autorequest="true"
src="http://www.beartronics.com:8080/examples/servlet/JDBCTest"/>
<view>
<view fontstyle="bold">
<simplelayout axis="x" spacing="4"/>
<text width="100" name="name" label="name" />
<text width="40" name="age" label="age" />
<text width="200" name="job" label="job" />
</view>

<view datapath="xml:/sqldata/row">
<text bgcolor="#ffcccc" width="100" name="name" datapath="name/text()" />
<text bgcolor="#ffcccc" width="40" name="age" datapath="age/text()" />
<text bgcolor="#ffcccc" width="200" name="job" datapath="job/text()" />
<simplelayout axis="x" spacing="4"/>
</view>
<simplelayout axis="y" spacing="4"/>
</view>
</canvas>

antun
01-21-2003, 08:10 AM
Would people be interested in a PHP version of this?

-Antun

wcwilson
01-23-2003, 10:10 AM
Thanks for the example! With it I was able to create a servlet serving up dynamic data for the contacts sample app. I just had to change the elements into attributes.

By the way, you can easily generate a contacts db with the contactsdata.xml file and XML spy (v5). (Convert/Export to Database). It worked fine with SQL Server.

Now I am just trying to figure out how to reload the data...

--Wayne

Grig
03-06-2003, 11:06 PM
Originally posted by antun
Would people be interested in a PHP version of this?

-Antun

That would be great!

hqm
03-07-2003, 04:41 AM
I should mention that there's nothing wrong with
directly constructing the XML "by hand" with print statements, i.e., out.write("<foo>"), out.write(result.getString("foo")), etc.

You would have to remember to do all the proper XML quoting and escaping of strings yourself though.

Grig
03-29-2003, 11:00 AM
I'd love to see that PHP version. ASP would be interesting too.

antun
04-01-2003, 09:48 AM
It's not done - I was wondering whether it would be worth investing the time in making one.

-Antun

Originally posted by Grig
I'd love to see that PHP version. ASP would be interesting too.

hqm
04-01-2003, 10:01 AM
Here's an example I have of generating an XML document from a database query using PHP




<?php

// Definitions for interchange of data

$DBSERVER="localhost";
$DBNAME="sw";
$DBUSER="postgres";
$DBPASS="";

function sw_connect() {
global $DBNAME;
global $DBUSER;
global $DBPASS;

$conn = pg_connect("dbname=$DBNAME user=$DBUSER password=$DBPASS");
return $conn;
}


// Return an XML description of a world
function generate_world_xml($world_id, $conn) {

////////////////////////////////////////////////////////////////
// XML Header
$xml .= "<?xml version=\"1.0\"?>\n";
////////////////////////////////////////////////////////////////

$xml .= "<areamap>\n";


$query = "select label, description, info
from worlds
where world_id = $world_id
order by label";

$result = pg_query ($conn, $query);

while ($row = pg_fetch_array($result)) {
$label = htmlspecialchars(htmlspecialchars($row["label"]));
$description = htmlspecialchars(htmlspecialchars($row["description"]));
$info = htmlspecialchars(htmlspecialchars($row["info"]));

$xml .= " <world name=\"" . $label . "\"\n";
$xml .= " description=\"" . $description . "\"\n";
$xml .= " info=\"" . $info . "\">\n";

// Loop over all buildings in this worlds
$query2 = "select building_id, label,
description, url, info, floors
from buildings
where world_id = $world_id";

$result2 = pg_query ($conn, $query2);

while ($row2 = pg_fetch_array($result2)) {

$building_id = $row2["building_id"];
$label = htmlspecialchars(htmlspecialchars($row2["label"]));
$description = htmlspecialchars(htmlspecialchars($row2["description"]));
$info = htmlspecialchars(htmlspecialchars($row2["info"]));
$url = htmlspecialchars(htmlspecialchars($row2["url"]));
$floors = htmlspecialchars($row2["floors"]);

$xml .= " <building name=\"" . $label . "\"\n";
$xml .= " description=\"" . $description . "\"\n";
$xml .= " url=\"" . $url . "\"\n";
$xml .= " floors=\"" . $floors . "\"\n";
$xml .= " info=\"" . $info . "\">\n";

$result3 = pg_query ($conn,
"select area_id, boundary, label, description, status,
url, area_number, color, boundary, floor
from areas
where (building_id = $building_id)");


while ($row3 = pg_fetch_array($result3)) {

$area_id = htmlspecialchars($row3["area_id"]);
$boundary = htmlspecialchars($row3["boundary"]);
$label = htmlspecialchars(htmlspecialchars($row3["label"]));
$description = htmlspecialchars(htmlspecialchars($row3["description"]));
$status = htmlspecialchars($row3["status"]);
$url = htmlspecialchars(htmlspecialchars($row3["url"]));
$area_number = htmlspecialchars($row3["area_number"]);
$color = htmlspecialchars($row3["color"]);
$floor = htmlspecialchars($row3["floor"]);
$boundary = htmlspecialchars($row3["boundary"]);

$xml .= " <area";
//$xml .= " area_id=\"" . $area_id . "\"\n";
$xml .= " boundary=\"" . $boundary . "\"\n";
$xml .= " name=\"" . $label . "\"\n";
$xml .= " description=\"" . $description . "\"\n";
$xml .= " floor=\"" . $floor . "\"\n";
$xml .= " status=\"" . $status . "\"\n";
$xml .= " url=\"" . $url . "\"\n";
$xml .= " number=\"" . $area_number . "\"\n";
$xml .= " color=\"" . $color . "\"/>\n";

}
$xml .= " </building>\n";

}

$xml .= " </world>\n";
}

$xml .= "</areamap>\n";

return $xml;

}

?>

Grig
04-01-2003, 10:16 AM
Sa-weeet That's awesome! Thanks for the post.

hqm
04-01-2003, 10:26 AM
Note, the double calls to "htmlspecialchars" probably isn't necessary - I think i was doubly quoting the entities because I wanted to display the results directly as HTML or something peculiar.