Browse DevX
Sign up for e-mail newsletters from DevX


Extend the JDK Classes with Jakarta Commons, Part II : Page 3

This second installment of a three-part series further explores components in Jakarta Commons and presents real world examples to demonstrate how you can use them in your projects.



The DBUtils framework is a thin wrapper around the JDBC API that makes using it easier. It lets a developer concentrate on querying or updating data and leaves the plumbing work of cleaning up resources to the framework.

This component is ideal for use in Data Access Objects. If an application doesn't require Hibernate or JDO for persistence but requires direct JDBC calls, using DBUtils speeds up development. The overview and examples hosted at the Jakarta site are very comprehensive. The javadoc also is easy reading, since the framework doesn't contain many classes.

How does it work? The SQL queries SELECT, INSERT, DELETE, or UPDATE can be passed to the query method of the QueryRunner class. Along with the query, an implementation to the ResultSetHandler interface should be passed. On execution of a SELECT query, the ResultSet object fetched is passed on to the handler. The handler can read the records, create domain objects, and return to the caller. The domain object created will be returned to the caller of the query method.

ArrayHandler, ArrayListHandler, BeanHandler, BeanListHandler, ColumnListHandler, KeyedHandler, MapHandler, MapListHandler, and ScalarHandler are some of the handlers available in the framework. However, you can write your own handler for a specific situation by implementing the ResultSetHandler interface.

The sample application in this section uses a modified version of the DBCP framework sample application to demonstrate this framework. The DatabaseContext and ContactInfoRepository classes are modified to use the DBUtils framework. Listing 9 is a code snippet of these modifications. The code passes the reference of the DataSource instance returned by the DBCP framework to the QueryRunner constructor. Therefore, the instance of the query runner will be available to all DAO classes in the system. (The source files can be found in the package in.co.narayanan.commons.dbutils in the src folder of the source code.)

Listing 9. Changes Done DatabaseContext Class for Using DBUtils
public class DatabaseContext implements IDatabaseContext { // Other declarations private QueryRunner qRunner; public DatabaseContext() throws DbException { init(); } private void init() throws DbException { // Initializing for DBCP dataSource = new PoolingDataSource(connectionPool); qRunner = new QueryRunner(dataSource); } // Other public and private methods public QueryRunner getQueryRunner() { return qRunner; } }

Listing 10 is a code snippet taken from the ContactInfoRepository class to demonstrate using QueryRunner to insert a record into the database. The update method takes the SQL query and its parameters and passes them to the prepared statement. The key point to note here is that the DBUtils framework handles resource cleanup and you need to handle only the SQLException for displaying an error to the user in the GUI.

Listing 10. Using QueryRunner to Insert Records
public void createContactInfo(ContactInfo contactInfo) throws DbException { String query = "INSERT INTO contactinfo(name,email) VALUES(?,?)"; try { context.getQueryRunner().update(query, new Object[] {contactInfo.getName(), contactInfo.getEmailAddress()}); } catch(SQLException e) { throw new DbException("Unable to create ContactInfo record", e); } }

Listing 11 creates an implementation of the ResultSetHandler interface and passes the instance to the query method in QueryRunner, along with the prepared statement parameters for selecting records from the database. It contains a custom ResultSetHandler to demonstrate its usage. An easier approach is to use BeanHandler, which uses reflection to automatically populate the ContactInfo domain object.

Listing 11. Using QueryRunner to Select Records from the Database
private static class ContactInfoRSHandlerByName implements ResultSetHandler { public Object handle(ResultSet results) throws SQLException { return getContactInfo(results); } private ContactInfo getContactInfo(ResultSet results) throws SQLException { if(results.next()) { ContactInfo contact = new ContactInfo(); contact.setName(results.getString("name")); contact.setEmailAddress(results.getString("email")); return contact; } else { return null; } } } public ContactInfo findByName(String name) throws DbException { String query = "select name, email from contactinfo where name=?"; try { return (ContactInfo)context.getQueryRunner().query(query, new Object[] {name}, new ContactInfoRSHandlerByName()); } catch(SQLException e) { throw new DbException("Unable to find ContactInfo record by name", e); } }

Thanks for your registration, follow us on our social networks to keep up-to-date