What is considered best practices when cleaning up JDBC resources and why? I kept the example short, thus just the cleaning up of the ResultSet.
finally
{
public static void close(Statement... statements) {
for (Statement stmt : statements) {
try {
if (stmt != null)
stmt.close();
} catch (SQLException se) {
}// nothing we can do
}
}
public static void close(Connection conn) {
try {
if (conn != null)
conn.close();
} catch (SQLException se) {
}// nothing we can do
}
public static void close(ResultSet rs) {
try {
if (rs != null)
rs.close();
} catch (SQLException se) {
}// nothing we can do
}
protected void closeAll(){
closeResultSet();
closeStatement();
closeConnection();
}
protected void closeConnection(){
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
/*Logger*/
}
connection = null;
}
}
protected void closeStatement() {
if (stmt != null) {
try {
ocstmt.close();
} catch (SQLException e) {
/*Logger*/
}
ocstmt = null;
}
}
protected void closeResultSet() {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
/*Logger*/
}
rs = null;
}
}
Nowadays JDK 7 gives you the easiest option to clean up resources:
String query = "select COF_NAME, PRICE from COFFEES";
try (Statement stmt = con.createStatement()) {
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
String coffeeName = rs.getString("COF_NAME");
float price = rs.getFloat("PRICE");
System.out.println(coffeeName + ", " + price);
}
}
The try statement ensures that each resource is closed at the end of the statement. See http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
This is my approach for JDK 6. If you have JDK 7+ you better use the approach I describe here https://stackoverflow.com/a/9200053/259237
private void querySomething() {
Connection connection = null;
PreparedStatement statement = null;
ResultSet rs = null;
try {
// get connection
// prepare statement
// execute query
// and so on
} catch (SQLException e) {
throw new MyException("Error while talking to database", e);
} finally {
close(connection, statement, rs);
}
}
// useful because you probably have more than one method interacting with database
public static void close (Connection connection, Statement statement, ResultSet rs) {
if (rs != null) {
try { rs.close(); } catch (Exception e) { _logger.warning(e.toString()); }
}
if (statement != null) {
try { statement.close(); } catch (Exception e) { _logger.warning(e.toString()); }
}
if (connection != null) {
try { connection.close(); } catch (Exception e) { _logger.warning(e.toString()); }
}
}
If you are writing a long running application you should consider connection pooling.
The Apache DBCP project does a lot of this work for you. You could also look at something like Spring JDBC or Hibernate as well.
The Spring stuff uses object pooling and adds some really nice methods for abstracting away JDBC nastiness.
ResultSet rs = //initialize here
try {
// do stuff here
} finally {
try { rs.close(); }
catch(SQLException ignored) {}
}