私は最近、基本的な jdbc 接続スキームの処理方法について教授と話し合っています。2 つのクエリを実行したいとします。これが彼の提案です。
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
}
}
}
私はこのアプローチが好きではなく、それについて 2 つの質問があります。
rs.close()
1.A) 「他のこと」を行う場所、または行内で例外がスローされた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-with-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 の明示的なクローズがないため、この方法を好まないと思いますが、ドキュメントですべてがクローズされていることが明らかである限り、彼女はそれで問題ないと私に言いました。同様の例で公式ドキュメントへのリンクを提供できますか、またはドキュメントに基づいて、このコードに問題がないことを示していますか?