As mentioned above, there are two additional types of statements available in JDBC- PreparedStatement and CallableStatement. CallableStatment is a proprietary way for making stored procedures in a JDBC compatible database. The best reference for this is on Sun's Javasoft website, because it is a changing and evolving standard.

PreparedStatement, however, is for statements that are executed multiple times with different values. For instance, you might want to INSERT several values, one after another. The advantage of the PreparedStatement is that it reduces the overhead of parsing an SQL string every time. Here is an example of how a PreparedStatement might be used:

PreparedStatement ps = null;

try {
    ps = c.prepareStatement("INSERT INTO book VALUES (?, ?, ?, ?)");
    ps.setInt(1, 495);
    ps.setString(2, "Zelazny");
    ps.setString(3, "Roger");
    ps.setString(4, "corwin@princesofamber.com");
} catch (SQLException se) {
    System.out.println("We got an exception while preparing a statement. Probably bad SQL.");
    se.printStackTrace();
    System.exit(1);
}

try {
    ps.executeUpdate();
} catch (SQLException se) {
    System.out.println("We got an exception while executing an update- possibly bad SQL, or check the connection.");
    se.printStackTrace();
    System.exit(1);
}

You can see that we prepare a statement in a similar fashion to before, except we use '?' instead of the actual value. Then you can use the setXXX methods on PreparedStatement to set those values directly. This can be nice because it avoids manual conversion of Java types to SQL types- for instance, the implementor does not have to worry about quoting or escaping when going to a CHAR type.

The other strength of the PreparedStatement is that we can use it over and over again. If we just set the values to be something else(in the same fashion as before, using the setXXX methods) we can change the values being inserted. Overall, the PreparedStatement mechanism is considerably more robust than the Statement class.

ResultSetMetaData is a class that is used to find information about the ResultSet returned from a "executeQuery" call. It contains information about the number of columns, the types of data they contain, the names of the columns, and other things like that. Here is an example of using the ResultSetMetaData to get the name of the first column in your ResultSet.

ResultSetMetaData rsmd = null;
try {
    rsmd = rs.getMetaData();
} catch (SQLException se) {
    System.out.println("We got an exception while getting the metadata: check the connection.");
    se.printStackTrace();
    System.exit(1);
}

String columnName = null;
try {
    columnName = rsmd.getColumnName(1);
} catch (SQLException se) {
    System.out.println("We got an exception while getting the column name: check the connection.");
    se.printStackTrace();
    System.exit(1);
}

System.out.print("The name of the first column is: '");
System.out.print(columnName);
System.out.println("'");

There are many other such methods in the ResultSetMetaData class, all of which are well documented in the JDK API documentation.

Finally, DatabaseMetaData is a class that can be used to fetch information about the database you are using- what kind of catalogs it has in it, what tables, what brand of database, and things like that. Let's just see what our user name is, and what URL we can reach the database at.

DatabaseMetaData dbmd = null;
try {
    dbmd = c.getMetaData();
} catch (SQLException se) {
    System.out.println("We got an exception while getting the metadata- check the connection.");
    se.printStackTrace();
    System.exit(1);
}

String username = null;
try {
    username = dbmd.getUserName();
} catch (SQLException se) {
    System.out.println("We got an exception while getting the username- check the connection.");
    se.printStackTrace();
    System.exit(1);
}

String url = null;
try {
    url = dbmd.getURL();
} catch (SQLException se) {
    System.out.println("We got an exception while getting the username- check the connection.");
    se.printStackTrace();
    System.exit(1);
}

System.out.println("You are connected to '" + url + "' with user name '" + username + "'");

Once again, the best source for the most current information about DatabaseMetaData's many other methods is in the JDK API documentation.