Java Gold 17のJDBC対策|PreparedStatement・ResultSet

JDBCは「接続する→SQLを準備する→実行する→結果を読む→閉じる」という流れで整理します。SQLを渡すタイミングと、実行メソッドの戻り値を区別して読みましょう。

SQLを渡すタイミングを確認する

オブジェクト主な取得方法役割
ConnectionDriverManager.getConnection(...)などDBへの接続とトランザクションを管理する
Statementcon.createStatement()実行時にSQL文字列を渡す
PreparedStatementcon.prepareStatement(sql)SQLを準備し、パラメータを設定して実行する
CallableStatementcon.prepareCall(sql)ストアドプロシージャなどの呼び出しに使う

PreparedStatementのSQL中の?には、setIntやsetStringなどで値を設定します。パラメータ番号は1からです。SQLをすでに準備しているため、通常は引数なしのexecuteQuery()やexecuteUpdate()を呼びます。Statementで使う「SQL文字列を渡す実行メソッド」と混同しないようにします。

ResultSetは結果を読むためのオブジェクトです。最初は先頭行の前にあるため、通常はnext()で行へ進んでから列を取得します。列番号も1からで、テーブルの定義順ではなくSELECTで取得した列の順序を確認します。PreparedStatementとResultSetの公式APIで確認できます。

戻り値・確定・解放をそれぞれ追う

  • executeQueryはResultSetを返します。結果セットを1つ返すSQLに使います。
  • executeUpdateは更新件数などをintで返します。結果セットを返さないSQLの扱いも確認します。
  • executeのbooleanは単純な成功・失敗ではありません。最初の結果がResultSetか、更新件数または結果なしなのかを表します。

新しい接続は原則としてauto-commitが有効です。setAutoCommit(false)で無効にした場合は、commitやrollbackがどこで呼ばれるかを確認します。closeをcommitの代わりとして扱わず、トランザクションを明示的に完了させてから閉じます。設定と動作はConnectionの公式APIを参照してください。

try-with-resourcesに複数のリソースを宣言した場合、閉じる順序は宣言の逆です。「結果を読める状態か」と「どのリソースが先に閉じられるか」を別々に追ってください。

例題2問:文の作成とリソース解放

接続やDBの前提が与えられている問題では、その前提に従ってAPIの使い方を判断してください。

例題1:JDBCリソースを閉じる順序

Connection c、そこから作ったPreparedStatement p、その結果ResultSet rをtry-with-resourcesにこの順で宣言しました。通常終了時のclose順を選んでください。

1つ選択してください

  • A. 常に順序は不定
  • B. c → p → r
  • C. r → p → c
  • D. p → r → c
例題1の正解・解説を見る

正解:C

正解は「r → p → c」です。

try-with-resourcesは後から宣言したリソースから解放します。結果セット、文、接続という依存の逆順になります。

  • A:try-with-resourcesは逆順を規定しています。
  • B:リソースのcloseは宣言と逆順です。
  • C:try-with-resourcesは後から宣言したリソースから解放します。結果セット、文、接続という依存の逆順になります。
  • D:結果セットより先にStatementを宣言しているため逆順とは合いません。

確認するポイント:複数リソースを同じtryへ書いても宣言順に閉じるのではありません。

仕様を確認するための公式資料:

問題ID:jg17-63082237bcd17e · この問題の訂正を連絡する

例題2:Connectionから文を取得する

Connection conからSQL実行用オブジェクトを取得する式として正しいものを2つ選んでください。

2つ選択してください

  • A. con.prepareStatement("SELECT name FROM item WHERE id = ?")
  • B. con.prepareStatement()
  • C. con.createStatement("SELECT name FROM item")
  • D. con.prepareCall("{call refresh_data()}")
例題2の正解・解説を見る

正解:A・D

PreparedStatementとCallableStatementは準備時にSQLを渡します。

PreparedStatementとCallableStatementは準備時にSQLを渡します。通常のStatementはcreateStatementで作って実行時にSQLを渡します。

  • A:SQLを準備してPreparedStatementを取得します。
  • B:SQL文字列が必要です。
  • C:createStatementにSQL文字列を渡すオーバーロードはありません。
  • D:プロシージャ呼び出し用のCallableStatementを取得します。

確認するポイント:メソッド名だけでなくSQLを渡すタイミングを確認します。

仕様を確認するための公式資料:

問題ID:jg17-8d2839ee617c7c · この問題の訂正を連絡する

JDBCの36問で復習する

問題演習の「出題分野」で「JDBC」を選びます。36問は教材の収録数で、試験の出題比率ではありません。

誤答した問題は「SQLを渡す場所」「パラメータ・列の番号」「カーソルの位置」「トランザクション」のどこで判断がずれたかを整理します。実行検証をする場合は、DBとドライバ、テーブル定義、初期データも問題の前提に合わせます。

関連する学習

本サイトの問題は、Java SE 17を学ぶためのオリジナル練習教材です。本試験の過去問やOracle公式の教材ではありません。編集・訂正の方針をご確認ください。