XQJ Part II - Setting up a session
An XQJ application always starts with accessing an XQDataSource object. Such object encapsulates all parameters and settings needed to create a session with a specific implementation and eventually execute XQuery expressions and process results.
Every XQJ driver has its own XQDataSource implementation. This XQDataSource object supports a number of implementation-specific properties. For each of these properties, a "getter" and "setter" method is provided.
Assume an application wants to query both an Oracle database, and some files located in "/usr/joe/data" with DataDirect XQuery. Two properties need to be specified, the base uri and the jdbc url to connect to the Oracle database (feel free to replace Oracle with your favourite database, be it SQL server, MySQL or yet another one),
DDXQDataSource xqds = new DDXQDataSource();
xqds.setBaseUri("/usr/joe/data");
xqds.setJdbcUrl("jdbc:xquery:oracle://sales:1521;SID=ORA10");
Or envision another Oracle specific implementation where the server parameters are specified in individual properties rather than through a jdbc url. It could be as follows,
OracleDataSource xqds = new OracleDataSource()
xqds.setServerName("sales");
xqds.setPortNumber(1521);
xqds.setSID("ORA10");
Having access to an XQDataSource object, what's next? An XQDataSource is a factory for XQConnection objects. The XQConnection object represents a session in which XQuery expression are executed.
Establishing such a session is straightforward,
XQConnection xqc = xqds.getConnection();
In case user credentials are needed, these can be specified as arguments to the getConnection() method,
XQConnection xqc = xqds.getConnection("joe", "topsecret");So far so good. Using the approach outlined above to create XQDataSource objects, makes the application dependent on a specific XQJ implementation. The proprietary classes DDXQDataSource and OracleDataSource are referenced. This is not necessarily wrong, there are scenarios where hard-coding the underlying XQJ implementation makes sense.
But often this is not desirable, XQJ is all about making your application independent from the underlying XQuery implementation. How can we make our application independent of the XQJ implementation? We'll show two approaches.
- using a Java properties files
- through JNDI
Assume all the XQDataSource properties are stored in a Java properties file, and in addition a property ClassName to identify the XQDataSource implementation to use.
For the DataDirect XQuery example above, the properties file would look as follows,
ClassName = com.ddtek.xquery3.xqj.DDXQDataSource
BaseUri = /usr/joe/data
JdbcUrl = jdbc:xquery:oracle://sales:1521;SID=ORA10
For the Oracle implementation,
ClassName = org.example.xqj.OracleDataSource
ServerName = sales
PortNumber = 1521
SID = ORA10
Using such properties file, an application can easily abstract out any hard-coded dependencies on the underlying XQJ implementation. The XQDataSource class is loaded through reflection and next it is simply a matter of passing in the properties.
// load the properties file
Properties p = new Properties();
p.load(new FileInputStream("/tmp/xqjds.prop"));
// create an XQDataSource instance using reflection
String xqdsClassName = properties.getProperty("ClassName");
Class xqdsClass = Class.forName(xqdsClassName);
XQDataSource xqds = (XQDataSource)xqdsClass.newInstance();
// remove the ClassName property
// the XQJ implementation will not recognize
// it and raise an error
p.remove("ClassName");
// set the remaining properties
xqds.setProperties(tmpProperties);
// create an XQConnection
XQConnection xqc = xqds.getConnection();
Of course, this is just an example, it might well be that for some applications another means to load the datasource properties is better suited.
Similar to JDBC, running in a J2EE environment, the XQDataSource object can be stored in a JNDI-enabled naming service. This allows your application to access the XQDataSource by simply specifying a logical name.
// get the initial JNDI context
Context ctx = new InitialContext();
// load the XQDataSource instance
XQDataSource xqds = (XQDataSource)ctx.lookup("xqj/sales");
// create an XQConnection
XQConnection xqc = xqds.getConnection();
For the readers with a JDBC background; JDBC has two mechanisms to establish a connection
- DriverManager
- DataSource
Don't look in XQJ for DriverManager-like functionality, XQJ doesn't offer this legacy functionality.
We have now learned how to create an XQConnection. In our next post we will do some real work, and show how to execute queries.
Labels: XQJ

0 Comments:
Post a Comment
<< Home