データの参照と更新
2.1 データの参照と更新
本節では、JDBCを利用してJavaプログラムからMariaDBデータベースへ接続し、データを検索する方法を学習します。
2.2.1 JDBCを利用したデータ検索の基本構文
MariaDBデータベースからデータを検索するには、以下の手順を行う必要があります。
① JDBC(java.sqlパッケージ)をインポートする。
例)import java.sql.*;
② JDBCドライバを読み込む。
例)Class.forName(ドライバ名);
③ データベースへ接続する。
例)Connection con = DriverManager.getConnection(URL,ユーザ名,パスワード);
④ SQL文(SELECT文)をデータベースに送るための準備を行う。
Statement smt = con.createStatement();
⑤ SQL文(SELECT文)をデータベースへ送信し、その結果セットを受け取る。
ResultSet rs = smt.executeQuery(SELECT文);
⑥ 受け取ったSQLの結果を処理する。
while(rs.next()){ rs.getString(テーブルの列名); }
上記手順の内、①から③については1.4節で学習したデータベース接続の処理になります。データを検索し表示するための処理は④から⑥になります。④ではデータベース接続の処理によって作られたオブジェクト変数のcreateStatement()メソッドを利用し、SQL文を送信するための準備を行なっています。その後executeQuery()メソッドを利用し、SELECT文をデータベースへ送信し、その結果セットを受け取ります。
⑥の処理は結果セットからデータを取り出すための処理になります。
2.2.2 ResultSet型のポインタ
executeQuery()メソッドを使ってデータの検索を行うと結果セットはResultSet型オブジェクトの戻り値として返されますが、オブジェクトの中のデータを利用するにあたり「ポインタ」(参照する列の位置情報)という概念を理解する必要があります。
ResultSet型のオブジェクトはデータベースのテーブルと同じように2次元の表のような形式でデータを管理しています。そのため、結果セットのデータを参照するためには「どの行のどの列のデータを参照するのか」を明確にする必要があります。その際、どの行なのかを表す内部的な目印のことを「レコードポインタ」と言います。また、レコードポインタが存在する参照可能な現在行のことを「カレントレコード」と言います。
図 2.2.1 結果セットとポインタ
データの検索を行うプログラムを実行する際の注意点データベースに登録されているデータが異なる場合、以降の章や項で作成するプログラムの実行結果や結果画面が説明の図と異なる場合がありますので注意が必要です。
データの検索を行うプログラム
このプログラムは、MariaDBへ接続し、テーブルに登録されたデータを全て表示するプログラムです。
➢ SampleSelect.java① ソース・フォルダー :myjdbc_kanda/src
② パッケージ :jp.co.f1.jdbc.ch02
③ 名前 :SampleSelect
④ 作成するメソッド・スタブの選択:public static void main(String[] args) にチェックを入れる
package jp.co.f1.jdbc.ch02; import java.sql.*; public class SampleSelect { //接続用の情報をフィールドに定数として定義 private static String RDB_DRIVE="org.mariadb.jdbc.Driver"; private static String URL="jdbc:mariadb://localhost/mybookdb"; private static String USER="bms"; private static String PASSWD="bms123"; public static void main(String[] args) { try{ Class.forName(RDB_DRIVE); Connection con = DriverManager.getConnection(URL,USER,PASSWD); Statement smt = con.createStatement(); String sql = "SELECT * FROM bookinfo"; ResultSet rs = smt.executeQuery(sql); //全てのデータを表示 while (rs.next()) { System.out.println("isbn -> " + rs.getString("isbn") + " title -> " + rs.getString("title") + " price-> " + rs.getString("price")); } smt.close(); con.close(); }catch (Exception e) { System.out.println("JDBCデータベース接続エラー"); } } }
実行結果
解説
このプログラムでは8行目から11行目でデータベースへ接続するために必要は情報を定数として定義しています。また、15行目から16行目では実際にデータベースに接続する処理を行なっています。ここまでの処理の流れは1章で作成したデータベースへ接続するプログラムと同様です。
17行目ではConnectionクラスのcreateStatement()メソッドを使用しSQL文を送信するための準備を行なっています。
18行目ではSELECT文を文字列として作成しています。
参照系のSQL文の場合executeQuery()メソッドを利用します。SELECT文をデータベースへ送信し、戻り値として結果セットを受け取っています。
ResultSet型の結果セットを扱う場合にはレコードポインタの初期位置に注意する必要があります。
executeQuery()メソッドを使って結果セットを生成した直後のタイミングでは、次の図のように、レコードポインタはレコードの先頭行の直前を指しています。この状態ではデータのある行を指していないため、データを参照することができません。
図 2.2.2 レコードポインタの初期位置
22行目から26行目はwhile文を利用して、結果セット内のデータを表示しています。
結果セットからデータを参照する場合には、レコードポインタを操作しつつデータを参照します。
22行目のwhile文の条件に記述されているnext()メソッドは、レコードポインタを1つ次の行に移動し、戻り値としてtrueを返します。また最終行にレコードポインタがあるときに実行するとfalseを返します。そのため、ポインタを1行ずつ移動しながらレコードの数分while文の中の処理を実行することができます。
while文の中では、レコードポインタが指している行の各列のデータを参照しprintln()メソッドで表示します。
このループ処理とデータ表示の流れは次の図のようになっています。
図 2.2.3 next()メソッドによるカーソルの遷移とデータの取得(ループ1周目)
図 2.2.4 next()メソッドによるカーソルの遷移とデータの取得(ループ2周目から6周目)
23行目から25行目に記述されているgetString(“isbn”)やgetString(“title”)、getString(“price”)が結果セットからデータを取得しています。結果セット内のデータを取得する場合、「レコードポインタが指している行のどの列のデータか」をメソッドの引数に指定します。
28行目と29行目ではデータベースとStatementの接続を解除しています。データベースとの接続が不要になった際には、必ず接続を解除しましょう。
カーソルを操作するメソッドこの節のプログラムではカーソルの操作にnext()メソッドを利用しました。カーソルを操作するメソッドには他にも次のようなメソッドがあります。
値を取得するメソッドこの節のプログラムでは値を取得するメソッドにgetString()メソッドを利用しましたが、値を取得するメソッドはデータ型ごとにあり、多くのメソッドが存在します。以下はその一部になります。
上記の他にも様々なメソッドが用意されていますが、全て「getXxxxx()」と命名されています。
データベースのフィールのデータ型とプログラム上でどのようにデータを扱うかによってメソッドを使い分けます。例えばこの節のプログラム内のpriceのデータのように、int型のフィールドの格納された値を、プログラムでは文字列として扱いたい場合、getSrting()メソッドを使い文字列として取得することもできます。ただし、実際のデータの型がgetXxxxx()で指定されたデータ型に変換できない場合はエラーになってしまうため注意が必要です。
ポイント
- データを検索する場合、executeQuery()を使用する
- execute Query()メソッドの引数にSELECT文を渡すと検索処理が実行される
- 検索したデータはResultSet型のオブジェクトとなる
- ResultSet型のオブジェクトからデータを参照する場合、カーソルの位置に注意する
- ResultSet型のオブジェクトからデータを参照する場合、getXxxxx()メソッドの引数に列名を指定する