Apr 08 2008

Using Apache Commons DBUtils and DBCP

Published by Tony under Java

For a project recently, I had the pleasure of working with both DBUtils and DBCP (Database Connection Pooling) from the Apache commons libraries. Both of these libraries together helped me to quickly create a simple, extensible DAO layer for my project. Both libraries include some great default features that I used right out of the box, without any configuration or fuss. In the post I’ll be talking about, and showing an example of using DBUtils. I will also show a quick and easy way to get a DataSource using DBCP.

Among other things DBUtils…

1. Removes the need to create or handle the life cycle of JDBC Connections or ResultSets. All you have to do is give it a DataSource object and it handles all of the connection opening/closing and data retrieval. As mentioned, you can get your DataSource using DBCP. Incidentally, you can also get a DataSource from your application container (Tomcat, JBoss, etc.), but I won’t be elaborating on that.

2. Automatically converts table rows to beans or Object arrays. This has got to be my favorite feature. If you create classes (Beans) whose property names match field names in a particular table (case-insensitive), DBUtils will automatically convert each row of the returned result set into a bean object. (Notice I used the general term “result set”, not the Java “ResultSet”, because I never have to deal with one.)

For instance, say you have a “Customers” table with the following fields:

  • customerId int
  • firstName varchar
  • lastName varchar
  • birthday datetime

Lets also say you have a Java class called Customers (you can actually call it anything) with the following fields and getters/setters conforming to the JavaBean specification:

  • Integer customerId
  • String firstName
  • String lastname
  • java.sql.Timestamp birthday

Lets use a very simple example. Let’s say you want to get a list of customers whose birthday falls between two dates. For example:

Query1

SELECT * FROM Customers c WHERE c.customerId BETWEEN '04/01/75' AND '04/20/75'

But, let’s make the query reusable. Let’s replace the dates with wildcard parameters.

Query1B

SELECT * FROM Customers c WHERE c.customerId BETWEEN ? AND ?

This allows us to insert any dates in place of the question marks. I’ll explain more later. Aside from this query you need three things: a DataSource, a QueryRunner, and a ResultSetHandler. You will find the latter two in the DBUtils package. Let’s assume for now that you already have your DataSource object. You can now create your QueryRunner object.

DataSource dataSource = getDataSource();
QueryRunner qr = new QueryRunner(dataSource);

Now that you have your QueryRunner created, you’ll need to create an instance of ResultSetHandler. Looking at the Javadocs you’ll notice that There are many implementations of the ResultSetHandler interface. I won’t go over them all, however, the two most useful to me have been BeanListHandler and ArrayListHandler. The former is used to convert table rows into beans and the latter returns a List<Object[]>, which reflects the structure of the underlying ResultSet. I’ll be using the BeanListHandler in my example.

String sql = "select * from Customers c where c.customerId between ? and ?";
Object[] params = new Object[]{"04/01/75", "04/20/75"};
ResultSetHandler rsh = new BeanListHandler(Customer.class);
List<Customer>; custList = (List<Customer>)qr.query(sql, params,rsh);

So, what just happened? Well, first we created the query string with question marks as “wildcard parameters.” I also just happen to have created an Object array called params that has two Strings in it. It’s probably fairly obvious at this point that, the SQL string and the array, when passed into the query() method, are combined in much the same way as in the String.format() method, or the old C printf function. If you’re not familiar with either of those, basically, the objects in the array take the place of the parameters, in order. So, the first element in the array will take he place of the first question mark and so on. The query method actually returns a list of objects, which makes the cast I’m doing “technically” an unsafe cast. However, since you specified the type that you want to get back when you created the BeanListHandler, you can be sure of the type you’re getting back.

So, at this point, you should have your list of Customer objects, properly populated, and ready to go. Looks pretty good right? it is. However, it’s very simple. We’re assuming that our result sets will map to one table, but if you’ve done any database work, you know that’s not always the case. What object would this query map to?

Query2

SELECT c.firstName, c.LastName, a.balance
FROM Customers c, Accounts a
WHERE c.customerId = a.customerId AND c.customerId = ?

Your result set will look like this:

  • Customers.firstName varchar
  • Customers.lastName varchar
  • Accounts.balance money

Your Customer class does not have a “balance” property, so if you used the BeanListHandler as in our previous example, you would not get the balance field at all. So, what are your options? Well, you could do one of two things. You could create an object for this specific result that has the fields you want (Maybe CustomerBalanceReport). Or you could use a different handler that allows variable fields and field types. In my project, I did the latter, using the ArrayListHandler in place of the BeanListHandler for my reports. The ArrayListHandler class has a no-arg constructor and is used in exactly the same way with the QueryRunner class as in the previous example. The only difference is that you will receive an ArrayList of Object arrays.

/*
 * In this example we are assuming we already have the following objects
 * Customer c; - a customer instance
 * String sql; - the query 2 above.
 */
ResultSetHandler rsh = new ArrayListHandler();
List<Object[]> resultList = (List<Object[]>)qr.query(sql, c.getCustomerId(), rsh);

Pretty similar to the other example, except for the difference in return types. Each Object in the Object array will contain three elements with the types String, String, and float (or possibly double) respectively. Something else I’ve demonstrated is that the query() method is overloaded. If you only have one replacement parameter, you can pass just that object in and it will map to the query(String sql, Object param, ResultSetHandler rsh) method.

I think that’s a good enough intro to DBUtils to get you started. But, how do you get a DataSource? Well, using DBCP you can create the following method in a controller class.

/*
 * Create a DataSource based on database properties
 */
private static DataSource createDataSource() {
    BasicDataSource d = new BasicDataSource();
    d.setDriverClassName(getProp("db.driver"));
    d.setUsername(getProp("db.user"));
    d.setPassword(getProp("db.pwd"));
    d.setUrl(getProp("db.url"));
    return d;
}

Pretty simple. And you can actually get a DataSource from your driver vendor. However, remember that the CP in DBCP stands for connection pooling. This is one of the advantages of using DBCPs DataSource over a typical vendor implementation. You can typically just use the BasicDataSource provided with the DBCP package and pass in the database connection info, which, in the example, I retrieve from a properties file. For instance getProp("db.driver") might return “com.microsoft.sqlserver.jdbc.SQLServerDriver”. This is a very simple way to get a DataSource. There are much more interesting and useful ways to automate DataSource acquisition. For instance, most application containers can inject a DataSource into your application for you. Tomcat actually uses the DBCP library to do this. You can also register your DataSource using JNDI and use a service locater to get it. I recommend using one of these methods for anything other than the simplest of apps. This was just an example to get you started trying out DBUtils with connection pooling.

A note about dependencies: DBUtils depends on Apache Commons Collections and DBCP depends on Apache Commons Pool.

No responses yet

Feb 22 2008

How Jim Blandy Pronounces “Subversion”

Published by Tony under Oddities

Found this by accident and thought it was hilarious. :)
How to Pronounce “Subversion”

No responses yet

Dec 21 2007

Using the New java.io.Console Class

Published by Tony under Java

The 1.6 release of the JDK included a new java.io.Console class, which adds some new features to enhance and simplify command-line applications. Notably, Console includes a method specifically for reading passwords that disables console echo and returns a char array; both important for security.

Scenario: Getting Username and Password
Getting a user’s username and password is probably one of the more common uses of the Console class. It’s fairly simple to do, but there are some things to look out for. Before you do anything else, you have to get a Console instance. Looking at the API, you’ll notice that Console has no public constructors. In fact, the only way to get a Console instance is by calling the System method:

Console con = System.console();

Simple enough, right? There is something you need to watch out for, however: The System.console() method can return null. According to the API:

If the virtual machine is started from an interactive command line without redirecting the standard input and output streams then its console will exist and will typically be connected to the keyboard and display from which the virtual machine was launched. If the virtual machine is started automatically, for example by a background job scheduler, then it will typically not have a console.

So, all you have to do is start it interactively, right? Well, sort of. This is the way it should work, but currently Eclipse (and some other IDEs) don’t yet support this feature “properly”, so if you try to run a program that calls System.console() from within your favorite IDE, it may return null. You have been warned.

The following code demonstrates one method for getting login information.

...
private static final int MAX_LOGINS = 3;
...
public boolean login()
{
  Console con = System.console();
  boolean auth = false;
 
  if (con != null)
  {
    int count = 0;
    do
    {
      String uname = con.readLine("Enter your username: ");
      char[] pwd = con.readPassword("Enter %s's password: ", uname);
      auth = authenticate(uname, pwd); // authenticate login info
      Arrays.fill(pwd, ' '); // delete password from memory
      con.writer().write("\n\n");  // output a couple of newlines
    } while (!auth && ++count < MAX_LOGINS);
  }
  return auth;
}

The first thing I’m doing here is getting a Console instance and checking to make sure it’s not null before proceeding. Once I have a Console instance, I can use the readLine and readPassword methods to get the login information. Both of these methods are overloaded, and include the following overloads:

public String readLine()
Reads a single line of text from the console.
public String readLine(String fmt, Object... args)
Provides a formatted prompt, then reads a single line of text from the console.
public char[] readPassword()
Reads a password or passphrase from the console with echoing disabled
public char[] readPassword(String fmt, Object... args)
Provides a formatted prompt, then reads a password or passphrase from the console with echoing disabled.

The versions I’m using combine prompting the user and getting input into one. If you really wanted to separate the two, you could use the Console.printf method to output your prompt and one of the no-arg methods above to get user input. That’s not necessarily incorrect, but definitely more verbose.

The readLine method takes a formatted String and a variable list of arguments; exactly like the System.out.printf method. The readLine method returns a line of input from the console, as a String, not including line termination characters. It returns null, if the end of the stream has been reached. The readPassword method is almost identical in functionality, except that it returns a char array of the user input. You’ll also notice that it disables console echo, so someone walking by can’t see what’s being typed.

Once I have the login information, I’m using a method called authenticate to check it. The implementation of this method is outside of the scope of this post. You could stub it out and test it, using hard-coded values.

Notice that, as soon as I’m done using the password information, I blank it out using the Arrays.fill utility method. This will minimize the lifetime of sensitive (password) data in memory.

Incidentally, I’ve also wrapped all of this in a loop that will run until the authenticate method returns true or until count is equal to MAX_LOGINS.

The Console class also has a few other methods, but the above four are the most interesting and likely to be the most-used. You might also use either the printf or format methods. According to the spec, these methods both behave identically to each other and exactly like System.out.printf. If you want to get the PrintWriter associated with this console, you can use the writer() method. Similarly, the reader() method retrieves the Reader object. Last but not least is the flush() method, which is a must since Console implements Flushable. Nothing surprising or groundbreaking with these last few methods, but I’d be remiss if I didn’t at least mention them.

4 responses so far

Dec 21 2007

JavaOne: Is it worth the cost?

Published by Tony under Random

I’ve always thought it would be cool to attend a JavaOne conference for a day or two. Unfortunately the location and costs have always deterred me. So, I’m wondering: Is it worth the cost of registration, the cost of a cross-country flight, and potential missed work? If you’ve been in the last few years, I’d like to hear your experiences and your feedback regarding the quality of the content. Thanks.

2 responses so far

Oct 31 2007

Creating a Network Protocol Stack

Published by Tony under Random

“The question is, ‘What’s been eating my time?’ Alex.” For those of you who have never watched Jeopardy and therefore didn’t catch the reference, shame on you. Buy a TV and worship watch it. :)

I’ve been instructed to create Data Link, Network, and Transport layers in my stack. The Data Link layer must use an “asynchronous” bit synchronization technique (start bits, stop bits, sync bits, etc.). This layer must also include a CRC-16 value in the frame. The Network layer is fairly simple, and will run a simple path vector routing protocol to build the forwarding table, and that’s about it. The Transport layer will use the “concurrent logical channels” approach which must implement a form of reliability using ACKs. Sounds fairly easy, but it’s taken me almost a week just to get the data Link layer completed. Luckily, I think it will be the most complex layer. My deadline is encroaching so…debugging tutorial? What debugging tutorial? Yeah, I’m still on it. I’ve actually recorded a few bits of it already. Anyway, back to the stack.

No responses yet

Oct 18 2007

Debugging Video Tutorial Update

Published by Tony under Java

Been trying to find the time to do this.  Last night I played with Wink software and was impressed.  I’ll definitely be using that to create my tutorials.  In order to get something out, I may break it up into two or more smaller tutorials: debugging basics, followed by more interesting features of Eclipse Debugging.

So stand by.  I’ll have something soon.  It’s just rather difficult when you’ve got work deadlines and graduate class deadlines hunting you down.  My wife also misses me, and you know she gets first dibs on my (non-existent) “free” time.  :)

No responses yet

Oct 18 2007

Yummy Web Service Goodness

Published by Tony under Java, Web

I’m not sure why I haven’t ventured into the realm of web services before this week. It probably has a lot to do with time (or lack thereof) and the type of projects I’ve worked on. But, I finally got my feet wet this week. My employer asked me to create a web service that publishes a service that we currently offer via a JSP web application. As I found out, the back-end logic is unnecessarily complex. To complicate matters the app is written using old-style JSP that is inundated with scriptlets and scattered across many smaller pages which are included based on if-then logic within the scriptlets. Yeah, it’s a mess. So, I read up on XML Schema and WSDL formats and created a WSDL. I know a lot of frameworks create the WSDL for you based on your objects, but I’ve heard that the WSDL-first approach is better for interoperability across platforms. I used Apache Axis as the WS framework because that’s what our project already used to consume web services, I just found out we’re switching from Tomcat to WebLogic and using the WebLogic web service framework. Nice. Good thing I used the WSDL-first approach. Should be a snap to convert. We’ll see.

No responses yet

Oct 08 2007

Coming Soon: Video Tutorial on Debugging

Published by Tony under Java

That’s right, I’m going to attempt to move into the realm of video tutorials. Not exclusively, but there are situations where it would be SO much faster and easier to just show how something works, rather than describe it in text and pictures. I’ve found a couple of programs that specialize in capturing desktop/application activity and turning it into a video (with sound). The first video will be on using the debugger included with the Eclipse IDE. My techniques can easily be adapted to just about any IDE with a debugger, so I won’t be doing multiple versions for other IDEs. Why a debugging tutorial? Look on any Java help forum and you’ll see people with runtime exceptions that are clueless about how track them down and fix them because they are also clueless about how to use a visual debugger! No, I’m not kidding. Anyway, I’ll probably rant more about that later when I post the video.  Until then, happy coding.

2 responses so far

Sep 17 2007

Cloning an Object Using Reflection

Published by Tony under snippets

Here’s a quick and dirty way to do a shallow copy of an object by overriding the clone method of Object. If you want to do deep copying, you’ll have to fidget with this a little more…or maybe I’ll do another blog about doing recursive cloning for deep copying. We’ll see.

In order to make this as generic and reusable as possible, create the clone method and put it in another class. For instance, maybe you have a Utility class or something like that, that has a lot of static methods in it or something? Well, let’s pretend you do and stick the static clone method in there.

public static Object clone(Object o)
{
  Object clone = null;
 
  try
  {
     clone = o.getClass().newInstance();
  }
  catch (InstantiationException e)
  {
     e.printStackTrace();
  }
  catch (IllegalAccessException e)
  {
     e.printStackTrace();
  }
 
  // Walk up the superclass hierarchy
  for (Class obj = o.getClass();
    !obj.equals(Object.class);
    obj = obj.getSuperclass())
  {
    Field[] fields = obj.getDeclaredFields();
    for (int i = 0; i < fields.length; i++)
    {
      fields[i].setAccessible(true);
      try
      {
        // for each class/suerclass, copy all fields
        // from this object to the clone
        fields[i].set(clone, fields[i].get(o));
      }
      catch (IllegalArgumentException e){}
      catch (IllegalAccessException e){}
    }
  }
  return clone;
}

Now, to use this method, just override clone() in your class, making sure your Utility class has been imported, and do the appropriate casting.

@Override
public MyClass clone()
{
  return (MyClass)Utility.clone(this);
}

2 responses so far

Aug 21 2007

Sending Serializable Object Data to Standard Out

Published by Tony under Oddities

I can’t really think of a good reason why you’d want t send object data to std out (System.out), but I recently had a project requirement that a parent process read the output from a child process. The child process output was complex, so I wondered if I could send it as object data instead of text. I was told, “You can’t do that”, which is when I knew that I would find a way. Turns out, it was easier than expected. As you’ve probably guessed, sending text would be faster. I didn’t time it against sending text, so I don’t know by how much. If you time it, let me know your results.

Because System.out is a PrintWriter, it doesn’t behave like a regular output stream in that it is meant to handle Strings. However, there is a write(byte[] b) method that enables object data to be sent in the following way:

// set up output streams
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
 
// write some Serializable objects to ByteArrayOutputStream
// using ObjectOutputStream wrapper
Set<integer> keys = resources.keySet ();
for(Integer key : keys) {
oos.writeObject(new Integer(42));
oos.writeObject(new Integer(100));
}
oos.close();
 
// send byte array to standard out
System.out.write(bos.toByteArray());

You can then read the output of the process and create a byte array from that output. Once you have the byte array you can re-create your objects like so:

ObjectInputStream ois =
    new ObjectInputStream(new ByteArrayInputStream(byteArr));
 
Integer i1 = (Integer)ois.readObject();
Integer i2 = (Integer)ois.readObject();
ois.close();

No responses yet

Next »