質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JDBC

JDBC(Java DataBase Connectivity)は、Javaとリーレーショナルデータベースに接続させる基本的なAPIです。Java上でSQLステートメントを発行することで、データベースの種類に影響を受ないDB操作を可能とします。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

5488閲覧

【Oracle JDK 8】try-with-resources文におけるResultSetのクローズ処理の扱いについて

退会済みユーザー

退会済みユーザー

総合スコア0

JDBC

JDBC(Java DataBase Connectivity)は、Javaとリーレーショナルデータベースに接続させる基本的なAPIです。Java上でSQLステートメントを発行することで、データベースの種類に影響を受ないDB操作を可能とします。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2020/04/27 01:07

編集2020/04/27 08:45

前提

Oracle JDK8を使って、Javaの勉強をしています。
現在は、JDBCで、データベースへのアクセスをしているのですが、
try-with-resources文におけるResultSetのクローズ処理の扱いで、よくわからないところがあります。

該当のソースコード

以下のコードは、テキストのコードを参考にして書いたものです。
コード1では、tryの宣言文の中に、ResultSetが宣言されています。
この場合、try-with-resources文を抜けた後、ResultSetがクローズされる、という理解をしております。

java

1// コード 1 2 public List<People> selectAll() throws SQLException { 3 4 List<People> peopleList = new ArrayList<People>(); 5 6 // データベースへの接続の取得、PreparedStatementの取得 7 try (Connection con = ConnectionManager.getConnection(); 8 Statement stmt = con.createStatement(); 9 // ここでResultSetが宣言されている 10 ResultSet res 11 = stmt.executeQuery("SELECT * FROM m_people")) { 12         // 結果の操作 13 while (res.next()) { 14 /* 省略 */ 15 } 16 } 17 18 return PeopleList; 19 } 20

それに対して、以下のコード2では、try句の中に、ResultSetが定義されています。

Java

1// コード 2 2public List<String> selectName(String section) throws SQLException { 3 4 List<String> nameList = new ArrayList<String>(); //氏名 5 6 // データベースへの接続の取得、PreparedStatementの取得 7 try (Connection con = ConnectionManager.getConnection(); 8 PreparedStatement pstmt 9 = con.prepareStatement("SELECT name FROM m_people WHERE section = ?")) { 10 11 // プレースホルダへの値の設定 12 pstmt.setString(1, section); 13 14 // ここでResultSetが宣言されている、これはクローズされる? 15 ResultSet res = pstmt.executeQuery(); 16 17 // 結果の操作 18 while (res.next()) { 19 /* 省略 */ 20 } 21 } 22 23 return nameList; 24 25 }

このコード2の場合、ResultSetはクローズされるのか疑問に思いました。

調べてみたこと

ResultSetの公式ドキュメントをあたってみました。

ResultSetオブジェクトは、このオブジェクトを生成したStatementオブジェクトが閉じられるとき、再実行されるとき、あるいは一連の複数の結果から次の結果を取り出すために使われるときに、自動的に閉じられます。
https://docs.oracle.com/javase/jp/8/docs/api/java/sql/ResultSet.html

それを踏まえての質問事項です。

(1) 上記の「調べてみたこと」の引用で、「一連の複数の結果から次の結果を取り出すために使われるときに、自動的に閉じられる」とのことです。これは、ResultSetを作成した後、ResultSet.next()でデータを読み出すことでしょうか?

(2) 上記のコード1では、tryの宣言文にResultSetが宣言されています。コード2では、tryの中にResultSetが宣言されています。この違いは何でしょうか? コード1では、tryの宣言文に明記しないと、自動的に閉じられないのでしょうか?

補足情報

java version 1.8.0_181

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/04/27 03:23

両方とも閉じられる。 コード1は蛇口と元栓を閉じる コード2は元栓を閉じる 両方とも元栓が閉じられてるから水はでないよねってこと
退会済みユーザー

退会済みユーザー

2020/04/27 03:54

asahina1979 様 コメントありがとうございます。 見当違いでしたら申し訳ありませんが、 元栓を閉める行為が、StatementあるいはPreparedStatementのクローズ(= ResultSetの自動クローズ)、 蛇口を閉める行為が、try句の中に明記されたReslutSetのクローズ、という解釈でしょうか。 となるとコード1でのtryの宣言の記述は書いても書かなくても一緒ですかね?
退会済みユーザー

退会済みユーザー

2020/04/27 04:22

元栓 = java.sql.Connection 蛇口 = java.sql.ResultSet
退会済みユーザー

退会済みユーザー

2020/04/27 04:36 編集

asahina1979 様 コメントありがとうございます。 そうなんですね。
guest

回答2

0

ベストアンサー

一連の複数の結果から次の結果を取り出すために使われるときに、自動的に閉じられます。

という文は,

このオブジェクトを生成したStatementオブジェクト

に掛かると思います.
どういう SQL でそうなるかパッと思いつきませんが, Statement から 1 つ目の ResultSet を取り出した後, 2 つ目の ResultSet を取り出すと, 1 つ目は自動で閉じられるということかと思います.

投稿2020/05/01 02:20

jimbe

総合スコア12646

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

コード1の、tryの()内に記述してあるResultSetの部分をtry句の中へ移動し、isClosed()メソッドを使ってチェックしてみました。
すると、クローズできているようでした。

asahina1979様の
元栓 = java.sql.Connection
蛇口 = java.sql.ResultSet
という例えていただきましたが、Connectionが閉じていれば、ResultSetも閉じたことになるということですね。

テキストの記述は、一応明示的に蛇口も閉じることを示した、というところでしょうか。

java

1// コード 1 検証 2 public List<People> selectAll() throws SQLException { 3 4 List<People> peopleList = new ArrayList<People>(); 5 6     // 外側でResultSetを宣言 7 ResultSet res; 8 9 // データベースへの接続の取得、PreparedStatementの取得 10 try (Connection con = ConnectionManager.getConnection(); 11 Statement stmt = con.createStatement();) { 12 13 ResultSet res = stmt.executeQuery("SELECT * FROM m_people") 14 15       // 結果の操作 16 while (res.next()) { 17 /* 省略 */ 18 } 19 } 20 21 // クローズできているかチェック 22 System.out.println("res : " + res.isClosed()); // => true クローズできている 23 24 return PeopleList; 25 }

投稿2020/04/27 05:20

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問