Недавно я поговорил с моим профессором о том, как обращаться с базовой схемой подключения jdbc. Предположим, мы хотим выполнить два запроса, это то, что он предлагает
public void doQueries() throws MyException{
Connection con = null;
try {
con = DriverManager.getConnection(dataSource);
PreparedStatement s1 = con.prepareStatement(updateSqlQuery);
PreparedStatement s2 = con.prepareStatement(selectSqlQuery);
// Set the parameters of the PreparedStatements and maybe do other things
s1.executeUpdate();
ResultSet rs = s2.executeQuery();
rs.close();
s2.close();
s1.close();
} catch (SQLException e) {
throw new MyException(e);
} finally {
try {
if (con != null) {
con.close();
}
} catch (SQLException e2) {
// Can't really do anything
}
}
}
Мне не нравится этот подход, и у меня есть два вопроса:
1.A) Я думаю, что если какое-либо исключение выбрано, когда мы делаем "другие вещи" или в строке rs.close()
или s2.close()
, тогда s1
не будет закрыт, когда метод завершится. Я прав об этом?
1.B) Профессор просит меня явно закрыть ResultSet (даже если в документации Statement ясно указано, что он закроет ResultSet). Она говорит, что Sun рекомендует его. Есть ли основания для этого?
Теперь это то, что я считаю правильным кодом для одного и того же:
public void doQueries() throws MyException{
Connection con = null;
PreparedStatement s1 = null;
PreparedStatement s2 = null;
try {
con = DriverManager.getConnection(dataSource);
s1 = con.prepareStatement(updateSqlQuery);
s2 = con.prepareStatement(selectSqlQuery);
// Set the parameters of the PreparedStatements and maybe do other things
s1.executeUpdate();
ResultSet rs = s2.executeQuery();
} catch (SQLException e) {
throw new MyException(e);
} finally {
try {
if (s2 != null) {
s2.close();
}
} catch (SQLException e3) {
// Can't do nothing
}
try {
if (s1 != null) {
s1.close();
}
} catch (SQLException e3) {
// Can't do nothing
}
try {
if (con != null) {
con.close();
}
} catch (SQLException e2) {
// Can't do nothing
}
}
}
2.A) Правильно ли этот код? (Гарантировано ли, что все будет закрыто при завершении метода?)
2.B) Это очень большой и многословный (и становится хуже, если есть больше заявлений). Есть ли более короткий или более элегантный способ сделать это без использования try-in-resources?
Наконец, это код, который мне больше всего нравится
public void doQueries() throws MyException{
try (Connection con = DriverManager.getConnection(dataSource);
PreparedStatement s1 = con.prepareStatement(updateSqlQuery);
PreparedStatement s2 = con.prepareStatement(selectSqlQuery))
{
// Set the parameters of the PreparedStatements and maybe do other things
s1.executeUpdate();
ResultSet rs = s2.executeQuery();
} catch (SQLException e) {
throw new MyException(e);
}
}
3) Правильно ли этот код? Я думаю, что моему профессору это не нравится, потому что нет явного закрытия ResultSet, но она сказала мне, что с ней все в порядке, пока в документации ясно, что все закрыто. Можете ли вы дать какую-либо ссылку на официальную документацию с аналогичным примером или на основе документации, показывающей, что с этим кодом нет проблем?