私は少し混乱している、私は下から http://en.wikipedia.org/wiki/Java_Database_Connectivity を読んでいた
Connection conn = DriverManager.getConnection(
"jdbc:somejdbcvendor:other data needed by some jdbc vendor",
"myLogin",
"myPassword" );
Statement stmt = conn.createStatement();
try {
stmt.executeUpdate( "INSERT INTO MyTable( name ) VALUES ( 'my name' ) " );
} finally {
//It's important to close the statement when you are done with it
stmt.close();
}
Conn Connectionを閉じる必要はありませんか? conn.close()が発生しない場合、実際に何が起こっていますか?
現在、どちらのフォームも閉じないプライベートWebアプリを持っていますが、重要なのは本当にstmt、conn、またはその両方ですか?
サイトは断続的にダウンし続けますが、サーバーはそれがデータベース接続の問題だと言い続けます。
Connection
の使用が終了したら、close()
メソッドを呼び出して明示的に閉じて、接続が保持している可能性のある他のデータベースリソース(カーソル、ハンドルなど)を解放する必要があります。
実際、Javaの安全なパターンは、ResultSet
、Statement
、およびConnection
を(この順序で)finally
ブロックで閉じることです。
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
// Do stuff
...
} catch (SQLException ex) {
// Exception handling stuff
...
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) { /* ignored */}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) { /* ignored */}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) { /* ignored */}
}
}
finally
ブロックは、(nullチェックを回避するために)少し改善できます。
} finally {
try { rs.close(); } catch (Exception e) { /* ignored */ }
try { ps.close(); } catch (Exception e) { /* ignored */ }
try { conn.close(); } catch (Exception e) { /* ignored */ }
}
ただし、これは非常に冗長なため、通常はヘルパークラスを使用してnullセーフヘルパーメソッドのオブジェクトを閉じ、finally
ブロックは次のようになります。
} finally {
DbUtils.closeQuietly(rs);
DbUtils.closeQuietly(ps);
DbUtils.closeQuietly(conn);
}
そして、実際には、 Apache Commons DbUtils には DbUtils
クラスがあり、これを正確に実行しているので、独自に記述する必要はありません。
使用後は、データベース/リソースオブジェクトを閉じることをお勧めします。 finally
ブロック内の接続、結果セット、およびステートメントオブジェクトを閉じる方が適切です。
Java7までは、これらすべてのリソースをfinally
ブロックを使用して閉じる必要があります。 Java 7を使用している場合、リソースを閉じるために次のようにできます。
try(Connection con = getConnection(url, username, password, "org.postgresql.Driver");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
) {
//statements
}catch(....){}
現在、con、stmt、rsオブジェクトはtryブロックの一部になり、Javaは使用後にこれらのリソースを自動的に閉じます。
お役に立てば幸いです。
Statement
とConnection
を閉じるだけで十分です。 ResultSet
オブジェクトを明示的に閉じる必要はありません。
Javaのドキュメントでは、Java.sql.ResultSet
について説明しています。
ResultSetオブジェクトは、そのStatementオブジェクトが閉じられるか、再実行されるか、複数の結果のシーケンスから次の結果を取得するために使用されるときに、それを生成したStatementオブジェクトによって自動的に閉じられます。
コメントをしてくれたBalusCに感謝します:「私はそれに依存しません。いくつかのJDBCドライバーはそれで失敗します。」
はい。結果セット、ステートメント、および接続を閉じる必要があります。接続がプールからのものである場合、接続を閉じると実際に再利用のためにプールに送り返されます。
通常、finally{}
ブロックでこれを行う必要があります。これにより、例外がスローされた場合でも、これを閉じることができます。
多くのフレームワークは、このリソースの割り当て/割り当て解除の問題を処理します。例えばSpringの JdbcTemplate 。 Apache DbUtils は、結果セット/ステートメント/接続をnullであるかどうかに関係なく閉じる(および閉じるときに例外をキャッチする)メソッドを備えています。
はい、接続を閉じる必要があります。それ以外の場合、データベースクライアントは通常、ソケット接続と他のリソースを開いたままにします。
実際には、try-with-resourcesブロックを使用すると、Javaがtryブロックを終了するときにすべての接続を閉じるのが最適です。
AutoClosableを実装するオブジェクトでこれを行う必要があります。
try (Connection connection = getDatabaseConnection(); Statement statement = connection.createStatement()) {
String sqlToExecute = "SELECT * FROM persons";
try (ResultSet resultSet = statement.execute(sqlToExecute)) {
if (resultSet.next()) {
System.out.println(resultSet.getString("name");
}
}
} catch (SQLException e) {
System.out.println("Failed to select persons.");
}
GetDatabaseConnectionの呼び出しが完了しました。 JDBC SQL接続またはプールからの接続を取得する呼び出しに置き換えます。