This design template has always served me well to ensure that Connection, Statement, and ResultSet objects are cleaned up when no longer needed.
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try
{
conn = DriverManager.getConnection(JDBC_CONNECTION_STRING);
ps = conn.prepareStatement("SELECT open,high,low,close FROM candle WHERE symbol=?");
ps.setString(1, "BARC");
rs = ps.executeQuery();
while(rs.next())
{
// do something with the results
}
}
catch (SQLException sqle)
{
// log the error
}
finally
{
// close the resources in reverse order of creation (i.e. ResultSet, PreparedStatement, Connection)
if (rs != null)
{
try
{
rs.close();
}
catch(SQLException sqle)
{
// log the error
}
}
if (ps != null)
{
try
{
ps.close();
}
catch(SQLException sqle)
{
// log the error
}
}
if (conn != null)
{
try
{
conn.close();
}
catch(SQLException sqle)
{
// log the error
}
}
}
PreparedStatement ps = null;
ResultSet rs = null;
try
{
conn = DriverManager.getConnection(JDBC_CONNECTION_STRING);
ps = conn.prepareStatement("SELECT open,high,low,close FROM candle WHERE symbol=?");
ps.setString(1, "BARC");
rs = ps.executeQuery();
while(rs.next())
{
// do something with the results
}
}
catch (SQLException sqle)
{
// log the error
}
finally
{
// close the resources in reverse order of creation (i.e. ResultSet, PreparedStatement, Connection)
if (rs != null)
{
try
{
rs.close();
}
catch(SQLException sqle)
{
// log the error
}
}
if (ps != null)
{
try
{
ps.close();
}
catch(SQLException sqle)
{
// log the error
}
}
if (conn != null)
{
try
{
conn.close();
}
catch(SQLException sqle)
{
// log the error
}
}
}
By declaring the Connection, Statement, and ResultSet before the initial try{} block you have access to them in the finally{} block so you can clean them up whether an exception occurs in the try{} block or not.