The xml:db API is a specification on the use of an XML
database from within Java. This is comparable to the
JDBC API, which allows you the use of an SQL database.
Unfortunately xml:db is very basic, compared to JDBC,
but it allows the most important tasks:
The current implementation assumes, that a fixed attribute
holds the documents ID. For example, this might be an attribute
called "id". In the case of a Tamino database, it might be
"ino:id".
Reading data from an XML database
First of all, any application accessing a database needs
some basic configuration. In the case of xml:db, we need
at least to specify a so-called driver and a collection.
This is done in an XML file:
<?xml version="1.0" encoding="UTF-8" ?>
<JMManagerConfiguration
xmlns="http://jaxme.ispsoft.de/namespaces/JMManagerConfiguration">
<Defaults>
<XmlDbManager>
<Driver>org.exist.xmldb.DatabaseImpl</Driver>
<URI>xmldb:exist://localhost:8081</URI>
<!-- This is for the eXist database, in the case of
Xindice you would use, for example, the driver
org.apache.xindice.client.xmldb.DatabaseImpl
and the URI
xmldb:xindice:///db/
-->
<IdAttribute>ID</IDAttribute>
<!-- By default this would be "id" -->
</XmlDbManager>
</Defaults>
<Configuration
localName="Session"
namespaceURI="http://jaxme.ispsoft.de/namespaces/examples/Session">
<ElementClass>de.ispsoft.jaxme.examples.session.ClsSession</ElementClass>
<HandlerClass>de.ispsoft.jaxme.examples.session.ClsSessionHandler</HandlerClass>
<ManagerClass>de.ispsoft.jaxme.XmlDbManager</ManagerClass>
</Configuration>
</JMManagerConfiguration>
Things you should note here:
- The configuration works much the same as the configuration
of the JDBC access. See RDBMS.html
for details on the JDBC configuration.
Unlike the JDBC case, there is a generic manager for all
document types (ManagerClass). Of course you still have the
ability to derive your own subclass of XmlDbManager and
configure that.
- As in the JDBC manager case, you do not need to use this
XML file. You might as well create your own instance of
XmlDbManager, configure that with
setDriver()
,
setURI()
,
setJmAnyElementClassName()
and
setJmContentHandlerClassName()
and be happy
with it. This is more straightforward, but you pay in
the long term, because finally you will find yourself
implementing a similar configuration scheme. (Experience
shows :-)
- The values given in the Defaults section can be
overwritten in the document type specific section
Configuration.
The recommended behaviour is naming the file
de/ispsoft/jaxme/JMManagerFactoryImpl.xml and
putting that file somewhere into your classpath. For example,
the following program would write out all current HTTP sessions
much like the "AddressPrinter":
import de.ispsoft.jaxme.examples.session.ClsSession;
import de.ispsoft.jaxme.*;
public class SessionPrinter {
public static void main(String[] args) throws Exception {
System.setProperty("de.ispsoft.jaxme.JMManagerFactory.uri",
"resource:com/mycompany/Configuration.xml");
JMManagerFactory factory = new JMFactory.getJMManagerFactory();
JMManager manager = factory.getJMManager(ClsSession.NAMESPACE_URI,
ClsSession.LOCAL_NAME);
String query = "Session[LASTACTION + EXPIRETIME > NOW()]";
for (java.util.Iterator iter = manager.select(query);
iter.hasNext(); ) {
ClsSession session = (ClsSession) iter.next();
System.out.println(session.toXML());
}
}
}
You could also read the configuration from a file or URL by
setting the following properties:
de.ispsoft.jaxme.JMManagerFactory=de.ispsoft.jaxme.JMManagerFactoryImpl
de.ispsoft.jaxme.JMManagerFactory.uri=file://c:\temp\Configuration.xml
or
de.ispsoft.jaxme.JMManagerFactory=de.ispsoft.jaxme.JMManagerFactoryImpl
de.ispsoft.jaxme.JMManagerFactory.uri=http://www..mycompany.com/Configuration.xml
And you could, of course, specify the property value from the command
line and not within the program.For details, see the
Writing data to an XML database
We'll now want to create a new HTTP session. It uses
the same property file as before:
import de.ispsoft.jaxme.examples.session.ClsSession;
import de.ispsoft.jaxme.*;
public class SessionAdd {
public static void main(String[] args) throws Exception {
JMManagerFactory factory = new JMFactory.getJMManagerFactory();
JMManager manager = factory.getJMManager(ClsSession.NAMESPACE_URI,
ClsSession.LOCAL_NAME);
ClsSession session = (ClsSession) manager.create();
session.eID = new Integer(126776);
session.eIPADDRESS = "134.23.1.7";
session.eLOGINTIME = new java.sql.Timestamp(System.currentTimeMillis());
session.eLASTACTION = session.eLOGINTIME;
session.eEXPIRETIME = new Short((short) 15*60);
session.eCOOKIE = "jH63fGdx";
session.eLANGUAGEID = new Integer(3);
manager.insert(session);
System.out.println("Document with ID " + session.eID + " was created.");
}
A similar example, the update of a row:
import de.ispsoft.jaxme.examples.session.session.ClsSession;
import de.ispsoft.jaxme.*;
public class SessionUpdate {
public static void main(String[] args) throws Exception {
JMManagerFactory factory = new JMFactory.getJMManagerFactory();
JMManager manager = factory.getJMManager(ClsSession.NAMESPACE_URI,
ClsSession.LOCAL_NAME);
java.util.Iterator iter = manager.select("myprefix:Session[@ino:id=37]");
if (iter.hasNext()) {
ClsSession session = (ClsSession) iter.next();
session.eLASTACTION = new java.sql.Timestamp(System.currentTimeMillis());
manager.update(session);
}
}
}
And finally, as you have probably guessed, an example for
deleting a row:
import de.ispsoft.jaxme.examples.session.ClsSession;
import de.ispsoft.jaxme.*;
public class SessionDelete {
public static void main(String[] args) throws Exception {
JMManagerFactory factory = new JMFactory.getJMManagerFactory();
JMManager manager = factory.getJMManager(ClsSession.NAMESPACE_URI,
ClsSession.LOCAL_NAME);
java.util.Iterator iter = manager.select("myprefix:Session[@ino:id=37]");
if (iter.hasNext()) {
ClsSession session = (ClsSession) iter.next();
manager.delete(session);
}
}
}
Noticed that these examples looked quite the same as their JDBC
counterparts did? Thats because the XmlDbManager is just another
manager.