Java 入門 【6】
データベースにアクセスする
-2010-10-15 Version 1.0
目 次 1 はじめに...1 1.1 データベース...1 1.2 データベースへのアクセス...2 2 MySQL へのアクセス ...3 2.1 準備...3 2.2 Connector/J のダウンロード・インストール...4 2.3 MySQL へのアクセス ...8 2.3.1 MySQL データベース接続環境 ...8 2.3.2 MySQL データベースのテーブルにアクセスする手順 ...9 2.3.2.1 JDBC ドライバを初期化する ...9 2.3.2.2 MySQL データベースに接続する ...10 2.3.2.3 テーブルにアクセスする...11 3 テーブルを検索・表示するプログラムを作成... 15 3.1 プログラムの概要...15 3.2 ソースコード例...15 3.3 eclipse でクラスを作成、実行 ...17 4 演習... 19 4.1 検索条件をつけましょう...19 5 演習解答例... 20 5.1 検索条件をつけましょう...20 6 付録... 23 6.1 TBD...23 7 改定履歴... 24 8 索引... 25
1
はじめに
本テキストでは、データベースにアクセスする方法を学びます。 ただし、本テキストでは以下については詳しい説明はいたしません。 MySQL SQL 文 1.1 データベース データベース(以降、DB と略記することがあります)は、ある目的のためにデータを管理・利 用するためのしくみです。その形態はデータをどのように管理するかで区分されます。 現在の主流のデータベースは、リレーショナルデータベース(Relational Database)です。Java のアプリケーション開発で、対象となるデータベースのほとんどは、このリレーショナルデ ータベース(以降、RDB と略記することがあります)です。ですから、本テキストでも RDB を 扱います。 代表的なRDB システムには次のようなものがあります。 表 1-1 代表的なデータベースシステム(RDB) データベースシステム名 概要 Oracle Oracle 社の RDB システム。 http://www.oracle.com/jp/products/database/index.html DB2 IBM 社の RDB システム。 http://www-06.ibm.com/software/jp/data/db2/SQL Server Microsoft 社の RDB システム。ASP.NET を利用した Web アプリケー ションのバックエンドとして利用されています。 http://www.microsoft.com/japan/sqlserver/ PostgresQL フリーで利用できるオープンソースのデータベースシステムです。 http://www.postgresql.jp/ MySQL オープン ソース のデータベースシステムで、世界でもっとも普及してい るとされています。 http://www-jp.mysql.com/
1.2 データベースへのアクセス 先に見たように、データベースにはいろいろな種類があります。アクセス方法もまちまちで す。しかし、アクセスするデータベースごとにJava のプログラムコードを作成するのであれ ば、とんでもないことです。 幸い、Java には、JDBC というデータベースにアクセスするためのアプリケーションインタ ーフェイス(API)が定められています。ですから、その JDBC に準じた実装1をすれば、一部 の情報を変更するだけで、色々なRDB にアクセスできます。 その様子を図に示します。 図 1-1 JDBC を使ってデータベースにアクセス 【JDBC ドライバ】 実際には、JDBC を使ってデータベースにアクセスするためのライブラリ(JDBC ドライバ) が必要です。MySQL の場合には、Connector/J というライブラリがよく利用されます。。 具体的な利用法についてはあとで詳しく説明します。 JDBC API Java application JDBC Connector/J MySQL PostgreSQL PostgreSQL JDBC Driver Oracle Oracle JDBC Driver JDBC API を使えば色々なデータ ベースに簡単にアクセスできます。 DB へのアクセス処理コード JDBC ドライバ(DB 専用のアクセス ライブラリ)が必要です。 java.sql パッケージに 含まれます。
2
MySQL へのアクセス
ここでは、MySQL データベースにアクセスするための基本的な手順を学びます。とくに、も っとも簡単な例として、テーブルの検索例を学びます。 2.1 準備 Java プログラムから MySQL に作成したデータ(テーブル)にアクセスするために、以下の準 備が必要です。 (1) MySQL をインストールします (2) MySQL にデータベース、テーブルを作成します (3) JDBC を経由してアクセスするためのライブラリをインストールします MyDQL の場合、Connector/J ライブラリ(JDBC ドライバ)をインストールします。 (4) MySQL にアクセスするためのユーザを作成します (3) の準備作業は、Java アプリケーションが動作する PC 環境に適用する必要があります。 その他の作業は、他の PC 環境に適用するのが普通です。もちろん、学習目的として、Java アプリケーションの動作 PC に MySQL をインストールしてデータベースを作成することも 良いです。 MySQL のデータベースを構築するのを、どなたか別の方にお願いできるのであれば、そうし てもらってください。ご自身で、MySQL データベースを作らなくてはならないのでしたら、「Java 入門 【6】 付録 - MySQL を導入する -」をご参照ください。MySQL のダウン
ロードからインストール手順、アクセス用のユーザ登録、データベースの作成と簡単なテー ブルの作成手順を説明しています。
2.2 Connector/J のダウンロード・インストール (1) MySQL Connectors ダウンロードサイトにアクセスします。 URL = http://dev.mysql.com/downloads/connector/ (2) "Connecto/J"を選択します。 図 2-1 MySQL Connectors ダウンロードサイト Connecto/J ダウンロードページが表示されます。 図 2-2 Connecto/J ダウンロードページ Connector/J を選択
(3) 下にスクロールし、zip ファイルのダウンロードを選択します。 mysql-connector-java-5.1.13.zip をダウンロードします。 図 2-3 zip ファイルのダウンロードを選択 mysql-connector-java-5.1.13.zip のダウンロードページが表示されます。 図 2-4 mysql-connector-java-5.1.13.zip のダウンロードページ(1) [Download]を選択
(5) 下にスクロールし、"≫ No thanks, just take me to the downloads!" を選択します。
図 2-5 mysql-connector-java-5.1.13.zip のダウンロードページ(2)
(4) 複数のダウンロードサイトが表示されますので、任意のサイトを選択します。
図 2-6 mysql-connector-java-5.1.13.zip のダウンロードサイトの選択
ダウンロードが開始されます。終了まで待ちましょう。
≫ No thanks, just take me to the downloads! を選択
HTTP, FTP いずれかお好み のサイトを選択します。
(5) ダウンロードしたファイルを展開します。 展開先は任意です。ここでは、C:¥mysql に展開しています。 図 2-7 mysql-connector-java-5.1.13.zip の展開 展開されたフォルダ内の、mysql-connector-java-5.1.13-bin.jar を使用します。どう使用する かは、後で説明します。 図 2-8 mysql-connector-java-5.1.13-bin.jar 以上で、JDBC ドライバの準備ができました。
2.3 MySQL へのアクセス ここからは、MySQL のデータベースのテーブルにアクセスする方法を学びます。 2.3.1 MySQL データベース接続環境 MySQL データベース環境はつぎのようになっているものとします。 詳しくは、「Java 入門 【6】 付録 - MySQL を導入する -」を参照してください。 図 2-9 MySQL データベース接続環境 JDBC 経由で MySQL のデータベースにアクセスするには、 パッケージ java.sql を使用します。 テーブルmembers には次のようなデータが入っているものとします。 表 2-1 members テーブルの内容
id name address phone mail memo
1 青木雄二 藤沢市東海岸7-50 0466-123-0123 [email protected] 言いだしっぺ 2 加藤智久 藤沢市なぎさ9-8-7 0466-123-1234 [email protected] リーダ 3 佐藤裕子 藤沢市江ノ島中央5-7 0466-123-2345 [email protected] 会計 4 田中一郎 藤沢市江ノ島東330 0466-123-3456 [email protected] サブリーダ 5 中村達也 藤沢市湘南町472-21 0466-123-4567 [email protected] 宴会幹事 MySQL データベースを導入した PC と、データベースにアクセスするプログラムを実行 するPC とは、同じ PC でも良いですし、ネットワークでつながっていれば別の PC でも かまいません。 Java application JDBC(java.sqlパッケージ) Connector/J MySQL DB へのアクセス処理コード データベース sampledb テーブル members 本テキストでは、この部分を 作成します。
2.3.2 MySQL データベースのテーブルにアクセスする手順 MySQL データベースのテーブルにアクセスする概略の手順を説明します。 図 2-10 MySQL データベースのテーブルにアクセスする概略の手順 各ステップについて詳しく説明します。 2.3.2.1 JDBC ドライバを初期化する 指定した名前のJDBC ドライバを初期化します。記述は次のようにします。 図 2-11 JDBC ドライバを初期化 【Class.forName】
宣言: public static Class forName(String className) throws ClassNotFoundException 引数: String 型 機能: 指定された文字列名を持つクラスの Class オブジェクトを返します。 戻り値: Class 例外: ClassNotFoundException 指定のクラスがないときにスローされます。 JDBC ドライバに関しては、Class.forName は指定した JDBC ドライバを、後述の DriverManager に登録する処理をします。ここで、指定する JDBC ドライバ名2(クラス 名)は "com.mysql.jdbc.Driver" です。これは、先にインストールしたMySQL 用の JDBC ドライバを示しています。 (1) JDBC ドライバを初期化する (2) MySQL データベースに接続する (3) テーブルにアクセスする (4) データベースをクローズする Class.forName("com.mysql.jdbc.Driver");
2.3.2.2 MySQL データベースに接続する MySQL データベース名、データベースユーザ名/パスワードを指定して、接続します。 このためには、DriverManager を使用します。 DriverManager を使うと、複数の JDBC ドライバを同時に管理・利用することができま す。つまり、複数のデータベースにアクセスすることができます。 図 2-12 MySQL データベースに接続 【DriverManager.getConnection】
宣言: public static Connection getConnection(String url, String user, String password) throws SQLException 引数:
url - jdbc:subprotocol:subname 形式のデータベース URL user - 接続するデータベースのユーザー password - ユーザーのパスワード 機能: 指定されたデータベースに接続します。 戻り値: Connection - データベースとの接続(セッション)を示すクラス 例外: SQLException - データベースアクセスエラーが発生した場合にスローされま す。 接続url は次のように記述します。 図 2-13 データベースへの接続 url (1) subprotocol MySQL の場合は、mysql とします。 (2) subname MySQL の場合は、//サーバホスト名[:ポート番号]/データベース名[?パラメタ] とします。
Connection db = DriverManager.getConnection(url, userid, password);
jdbc:subprotocol:subname
//サーバホスト名[:ポート番号]/データベース名[?パラメタ]
・サーバホスト名 サーバホスト名は、IP アドレスを直接記載しても良いです。また、同一 PC 上のデ ータベースの場合には、サーバホスト名は、localhost となります。 ・ポート番号 省略できます。 ・データベース名 MySQL サーバに作成したデータベースの名前を記載します。 ・パラメタ情報 認証やネットワークなど、さまざまなパラメタがありますが、ここでは、文字コー ドに関するパラメタだけを使ってみます。 【接続url の具体例】 本テキストで使用する例は、次の通りです。 (1) 同一 PC の場合 "jdbc:mysql://localhost/sampledb (つづきます) ?useUnicode=true&characterEncoding=Windows-31J" (2) 別 PC の場合 "jdbc:mysql://xxx.xxx.xxx/sampledb (つづきます) ?useUnicode=true&characterEncoding=Windows-31J" useUnicode=true JDBC ドライバで、Unicode を使用します。 characterEncoding=Windows-31J
MySQL データベースでは、Windows-31J を使用します。Windows-31J は、Windows-31J は、Windows 環境で用いられている文字コードです。特殊文字として、NEC 特殊文字(①、㈱ など)、IBM 特殊文字(髙、﨑 など)などをサポートしています。 2.3.2.3 テーブルにアクセスする テーブルにアクセス、といってもテーブルの作成・削除・データの追加・データの変更・ データの検索など、やりたいことはさまざまです。ここでは、もっとも簡単な例として、 テーブルの検索例を学びます。 データベースのテーブルを検索し、各行のデータを取得するには、Connection クラス、 PreparedStatement クラスと ResultSet クラスを使用します。それらの大まかな関連を 図に示します。
図 2-14 基本的なデータベース検索でのクラス使用例
おおまかな手順を説明します。
(1) Connection::prepareStatement()メソッドを使用し、PreparedStatement オブジェク トを取得します。
【Connection::prepareStatement】
宣言: public PreparedStatement prepareStatement(String sql) throws SQLException 引数: sql - 1 つ以上の '?' IN パラメータプレースホルダーを含めることができる SQL 文(文字列) 機能: パラメータ付き SQL 文をデータベースに送るための PreparedStatement オブジェクトを生成します。 戻り値: PreparedStatement オブジェクト 例外: SQLException - データベースアクセスエラーが発生した場合、このメソッド がクローズされた PreparedStatement で呼び出された場合 引数の sql で説明している「パラメータプレースホルダー」は、SQL 文に含める具体的 な値を別途指定し、'?' (パラメータマーカといいます)の場所を置き換えることができるも のです。後で、例を示します。 + execute(): boolean + executeQuery(): ResultSet PreparedStatement + main(String[] args): void
DBアクセスアプリケーション
+ next(): boolean
+ getString(String columnLabel): String ResultSet
+ prepareStatement(String sql): PreparedStatement Connection
(2) PreparedStatement::setString()メソッドを使用し、PreparedStatement オブジェク トのパラメータプレースホルダーに値をセットします。
この処理は、パラメータプレースホルダーに'?'が無い場合には、必要ありません。 【PreparedStatement:: setString】
宣言: public void setString(int parameterIndex, String x) throws SQLException 引数: parameterIndex - 最初のパラメータは 1、2 番目のパラメータは 2、... とし ます x - パラメータ値 機能: 指定されたパラメータを指定されたパラメータプレースホルダーのパラメー タマーカーの値として設定します。 戻り値: PreparedStatement オブジェクト 例外: SQLException - parameterIndex が SQL 文のパラメータマーカー(?)に対応 しない場合、データベースアクセスエラーが発生した場合、このメソッドがク ローズされた PreparedStatement で呼び出された場合 【例】以下の場合、sql 文は以下と同じ効果になります。
"SELECT * FROM MEMBERS WHERE NAME LIKE '青木%' " ↑
String sql = "SELECT * FROM MEMBERS WHERE NAME LIKE ? "; PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, "青木%");
(3) PreparedStatement::executeQuery()メソッドを使用し、SQL 文を実行します。
【PreparedStatement:: executeQuery】 宣言: public ResultSet executeQuery()
throws SQLException 引数: なし 機能: PreparedStatement オブジェクトの SQL クエリーを実行し、そのクエリー によって生成された ResultSet オブジェクトを返します。 戻り値: ResultSet オブジェクト 例外: SQLException - データベースアクセスエラーが発生した場合、このメソッド がクローズされた PreparedStatement で呼び出された場合、または SQL 文 が ResultSet オブジェクトを返さない場合 (4) ResultSet オブジェクトから必要なデータを取得します
たとえば、members テーブルを
SELECT ID, NAME, ADDRESS FROM MEMBERS
で検索すると、ResultSet は次のような仮想的なテーブルのように検索結果データを保持 します。 表 2-2 ResultSet のイメージ例 ID NAME ADDRESS 1 青木雄二 藤沢市東海岸7-50 2 加藤智久 藤沢市なぎさ9-8-7 3 佐藤裕子 藤沢市江ノ島中央5-7 4 田中一郎 藤沢市江ノ島東330 5 中村達也 藤沢市湘南町472-21 ResultSet は、現在の行データを示す、「カーソル」を保持しています。初期状態では、 カーソルは、最初の行の一つ前を示しています。つまり、諸雉様態のカーソルはどの行 も示していません。 ResultSet が保持している各行のデータを取得するには、例えば、つぎのようにします。 1) ResultSet::next() で次の行に移動する 2) ResultSet::getString(列名) で、指定した列名の列データを取得する 3) 1) と 2)を行データが終了するまで繰り返す。 【ResultSet:: next】
宣言: public boolean next()
throws SQLException 引数: なし 機能: カーソルを現在の位置から 1 行順方向に移動します。 戻り値: true - 新しい現在の行が有効な場合 false - それ以上行がない場合 例外: SQLException -データベースアクセスエラーが発生した場合、またはこのメソ ッドがクローズされた結果セットで呼び出された場合 【ResultSet:: getString】
宣言: public String getString(String columnLabel) throws SQLException 引数: columnLabel - 列の名前 機能: カーソルを現在の位置から 1 行順方向に移動します。 戻り値: 列の値 例外: SQLException -データベースアクセスエラーが発生した場合、またはこのメソ ッドがクローズされた結果セットで呼び出された場合
3
テーブルを検索・表示するプログラムを作成
では、これまでの内容を元に、MySQL のデータベースにあるテーブルを検索し、結果をコン ソールに表示するプログラムを作成しましょう。 3.1 プログラムの概要 以下のようなプログラムを作ってみましょう。出力内容はお好きなように書いてみてくださ い。 プロジェクト名: java_06 パッケージ名 : jp.lites.study.java クラス名: MySQLAccessSample テーブル検索:SELECT * FROM MEMBERS 結果表示:
ID の値, NAME の値, ADDRESS の値, PHONE の値, MAIL の値, MEMO の値
3.2 ソースコード例 ソースコード例を示します。 リスト 3-1 MySQLAccessSample.java line MySQLAccessSample.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package jp.lites.study.java; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class MySQLAccessSample {
/**
* @param args */
public static void main(String[] args) {
line MySQLAccessSample.java 18 19 20 21 22 23 24 25 26 27 28 29 30 32 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
String userid = "root";
String password = "mysql"; // 仕事では、パスワードをこんなところに直接書いてはいけません よ。 Connection db = null; PreparedStatement ps = null; ResultSet rs = null; try { Class.forName("com.mysql.jdbc.Driver");
db = DriverManager.getConnection(url, userid, password); System.out.println("MySQL にアクセスできました。"); // select * from members;
ps = db.prepareStatement("select * from members"); rs = ps.executeQuery(); while (rs.next()) { System.out.println(rs.getString("name") + "," + rs.getString("address") + "," + rs.getString("phone") + "," + rs.getString("mail") + "," + rs.getString("memo")); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { try { if (ps != null) { ps.close(); } if (db != null) { db.close(); System.out.println("MySQL データベースを close しました。");
line MySQLAccessSample.java 56 57 58 59 60 61 62 63 64 65 } } catch (SQLException e) { e.printStackTrace(); } } } } 【16 行目】データベースアクセス url を定義しています。 String url = "jdbc:mysql://192.168.1.8/sampledb?useUnicode=true&characterEncoding=Windows-31J"; このサーバアドレスは、ご自身の環境に合わせて変更してください。先に説明したよう に、このMySQLAccessSample を実行する PC と同一の PC に MySQL データベースサ ーバが動作している場合には、 localhost を指定してください。
【37~41 行目】rs.next() が null で無い限り、つまり、ResultSet にデータ行がある限 り、各行のデータを取得しています。
3.3 eclipse でクラスを作成、実行
上記のクラスをeclipse で作成、実行みましょう。 実行結果例を図に示します。
4
演習
4.1 検索条件をつけましょう
サンプルのMySQLAccessSample クラスを参考に、下記の条件で検索した結果コンソールに 表示するするプログラムを作成、実行してください。
【検索条件】ADDRESS が、'藤沢市江ノ島' のメンバーの ID, NAME, ADDRESS を取得し ます。
5
演習解答例
5.1 検索条件をつけましょう
サンプルのMySQLAccessSample クラスを参考に、下記の条件で検索した結果コンソールに 表示するするプログラムを作成、実行してください。
【検索条件】ADDRESS が、'藤沢市江ノ島' のメンバーの ID, NAME, ADDRESS を取得し ます。 ソースコード例と実行結果例を載せます。 【ソースコード例】 リスト 5-1 ソースコード例 line Drill_01.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package jp.lites.study.java; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class Drill_01 {
/**
* @param args */
public static void main(String[] args) {
String url =
"jdbc:mysql://192.168.1.8/sampledb?useUnicode=true&characterEncoding=Windows-31J"; String userid = "root";
String password = "mysql";// 仕事では、パスワードをこんなところに直接書いてはいけませんよ。 Connection db = null;
PreparedStatement ps = null; ResultSet rs = null;
line Drill_01.java 26 27 28 29 30 32 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 try { Class.forName("com.mysql.jdbc.Driver");
db = DriverManager.getConnection(url, userid, password); System.out.println("MySQL にアクセスできました。");
// select id, name, address from members where address like '藤沢市江ノ島%';
ps = db.prepareStatement("select id, name, address from members where address like ?"); ps.setString(1, "藤沢市江ノ島%"); rs = ps.executeQuery(); while (rs.next()) { System.out.println(rs.getString("id") + "," + rs.getString("name") + "," + rs.getString("address")); } } catch (ClassNotFoundException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } catch (SQLException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } finally { try { if (ps != null) { ps.close(); } if (db != null) { db.close(); System.out.println("MySQL データベースを close しました。"); } } catch (SQLException e) { e.printStackTrace();
line Drill_01.java 64 65 66 67 68 } } 【実行結果例】 MySQLにアクセスできました。 3,佐藤裕子,藤沢市江ノ島中央5-7 4,田中一郎,藤沢市江ノ島東330 MySQL データベースを close しました。