Statement
注: Statementオブジェクトがクローズされるとき、その現在のResultSetオブジェクトが存在すれば、それもクローズされます。
Statement (Java Platform SE 8 )
ResultSet
注: ResultSetオブジェクトは、このオブジェクトを生成したStatementオブジェクトがクローズされるとき、再実行されるとき、または一連の複数の結果から次の結果を取り出すのに使用されるときに、そのStatementによって自動的にクローズされます。
ResultSet (Java Platform SE 8 )
ということなので、 Statement
の方を確実に close()
していれば、 ResultSet
の close()
は書かなくても良いっぽい。
package sample.jta;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Main {
public static void main(String[] args) throws ClassNotFoundException {
Class.forName("org.h2.Driver");
try (Connection con = DriverManager.getConnection("jdbc:h2:mem:test", "sa", "")) {
try (Statement stmt = con.createStatement()) {
stmt.executeUpdate("create table if not exists foo(id number(10), code varchar(20))");
}
try (PreparedStatement ps = con.prepareStatement("insert into foo values (?, ?)")) {
ps.setLong(1, 1L);
ps.setString(2, "hoge");
ps.executeUpdate();
ps.setLong(1, 2L);
ps.setString(2, "fuga");
ps.executeUpdate();
}
ResultSet rs;
try (PreparedStatement ps = con.prepareStatement("select * from foo")) {
rs = ps.executeQuery();
while (rs.next()) {
long id = rs.getLong("id");
String code = rs.getString("code");
System.out.println("id=" + id + ", code=" + code);
}
System.out.println("(1) rs.isClosed()=" + rs.isClosed());
}
System.out.println("(2) rs.isClosed()=" + rs.isClosed());
} catch (SQLException e) {
e.printStackTrace(System.err);
}
}
}
実行結果
id=1, code=hoge
id=2, code=fuga
(1) rs.isClosed()=false
(2) rs.isClosed()=true
PreparedStatement
が close
されたら ResultSet
も close
されてる。
追記
コネクションプールがStatementもプールするかもしれないのでResultSetも明示的に閉じて置いた方が無難だと思うなー
— うらがみ⛄ (@backpaper0) October 29, 2017
ややこしいケースもありそうなので、明示的に close()
するのが良さそうです。