Apache Derby/Programming

提供: fukudat
移動: 案内検索

100% pure Java の関係データベース管理システム(RDBMS)であるApache Derbyを Java のプログラムから使用する方法を説明する.

本稿の目的は,Apache Derby を使った JDBCプログラムの初歩を例示することにあり,オブジェクト指向プログラミングを解説することを目的としていないので,実用的な応用に対しては不適切な部分があることに注意していただきたい.(例:全部が main 関数に記述されている,2度実行できないなど)

目次

準備

Java プログラムの開発には Eclipse を使用することを前提にするので,EclipseのインストールApache Derbyのインストールは完了しているものとする.

  • Eclipse を起動.
    • Windows の場合、c:\eclipse\eclipse.exe を実行。 (ただし,c:\eclipseはEclipseのインストールディレクトリ)
    • Linux の場合、/opt/eclipse/eclipse を実行。 (ただし,/opt/eclipseはEclipseのインストールディレクトリ)
  • 新規プロジェクトを作成する .
    • プルダウンメニュー "File" ⇒ "New" ⇒ "Project..." ⇒
    • "Java Project" を選んで Next ⇒
    • 適当なプロジェクト名(例えば sample)を入力して Finish
    derby-programming-1.png
  • 作成したプロジェクトで、Apache Derby を使えるようにする.
    • Java Perspective を開く (ウィンドウ右上の Open Perspective アイコンを押して、Java を選択)
    • Package Explorer view (エキスプローラ風) 中に,さっき作成したプロジェクトを見つけ、右クリック ⇒ Apache Derby ⇒ Add Apache Derby nature
    derby-programming-2.png
  • ここで,もし下の図のようなエラーが出るようだったら…
    Derby-5.png
    • プルダウンメニュー "Window" ⇒ "Preferences..." ⇒ "Java/Build Path/Classpath Variables" を開き
    • New ボタンを押して,"ECLIPSE_HOME=c:\eclipse" を追加(下の図参照.c:\eclipse はEclipseをインストールしたトップディレクトリ)
    • "OK" ⇒ "OK"... で完了.下図のようにエラーが消えるはず.
    Derby-6.png

ここまでは,Apache Derbyの対話的な使い方の準備と同じ.

プログラムからデータベースに接続する

  • まずクラスを新しく作ろう.
    • Package Explorer view でプロジェクトを右クリックして New ⇒ Class を選択.
    • New Java Class というダイアログボックスが出てくるので,Name: に適当クラス名 (ここでは Sample としよう.Javaのクラス名は普通大文字で始める) を入れて OK を押す.
    derby-programming-3.png
  • mainメソッドを作って,データベースに接続しよう.
    • 真ん中のテキストエディタに Sample.java が現れているはずなので,そこに以下の内容を打ち込む.
    derby-programming-4.png
import java.sql.*;

public class Sample {
    public static void main(String[] argv) {
        try {
            Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
            String url = "jdbc:derby:myDB;create=true";
            Connection conn = DriverManager.getConnection(url);
            conn.close();
        } catch (SQLException e) {
            System.err.println(e.getMessage());
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }
}
  • エラー (赤いバッテン印) がなければ,このプログラムを実行してみよう.
    • プルダウンメニューの "Run" ⇒ "Open Run Dialog..." を選択.
    • Java Application を右クリックして "New" を選択.
    • すると次のような画面ができるので,何も変更せずに "Run" ボタンを押す.
    derby-programming-5.png
  • もしうまくいっていれば,何も言わずに瞬時に黙ってプログラムは終了するはず.
    • 成功したかどうかは,Package Explorer のあいているところを右クリックして,"Refresh" してみよう.myDB というフォルダが作成されていることが確認できるはずだ.

解説

int c = stmt.executeUpdate("DELETE FROM 酒 WHERE 製造元='石本酒造'");
  • このSQL文は「酒テーブルのレコードのうち,製造元がが石本酒造であるようなものの削除せよ」という意味である.
  • Statementオブジェクトの executeUpdate() メソッドを呼び出している.このメソッドはDeleteされたレコード数が返されるので,それを変数cで受け取っている.

PreparedStatement の使い方

これまで見てきたJDBCの使い方は,毎回文字列としてSQL文をデータベースに送りつけていた. データベースはそのたびにSQL文をコンパイル(解釈して実行プランを作成し,それを最適化)しなければならない. 同じような内容のSQLを繰り返し実行する必要がある場合には,このような方法は極めて効率が悪い. そこで,PreparedStatement という仕組みが用意されていて,データベースがSQL文を一度解釈したら,それを何度も使いまわして,パラメータを変えて実行させることができる.

ここではINSERT文を例にとって説明する.Sample.javaのmain関数を次のように書き換えよう.

...前略...
Connection conn = DriverManager.getConnection(url);
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PreparedStatement stmt1 = conn.prepareStatement("INSERT INTO 酒 VALUES(?, ?)");
for (;;) {
    System.out.print("酒名 = ");
    System.out.flush();
    String name = in.readLine();
    if (name.length() == 0)
        break;
    System.out.print("製造元 = ");
    System.out.flush();
    String make = in.readLine();
    stmt1.setString(1, name);
    stmt1.setString(2, make);
    stmt1.execute();
}
Statement stmt2 = conn.createStatement();
ResultSet rs = stmt2.executeQuery("SELECT 名前, 製造元 FROM 酒");
while (rs.next()) {
    String name = rs.getString(1);
    String make = rs.getString(2);
    System.out.println(name + ", " + make);
}
conn.close();
...後略...
  • エラーがないことを確認したら,緑三角ボタンを押して実行してみよう.
    • 画面下の Console view に酒名の入力を促す文字が現れるはずなので,その後ろに適当な(しかしまだテーブルには存在しない)酒の名前を入力してエンター.
    • 続いて製造元を聞いてくるので,製造元を入れてエンター.この繰り返し.
    • 酒名に対して,何もいれずにエンターを押すと,データの入力は終了し,その時点でテーブルに入っている酒とその製造元がすべてリストアップされる.
      derby-programming-8.png

解説

PreparedStatement stmt1 = conn.prepareStatement("INSERT INTO 酒 VALUES(?, ?)");
for (;;) {
    ...中略...
    stmt1.execute();
}
  • データベース接続オブジェクトの prepareStatement()メソッドを使って,INSERT文を準備 (prepare) し,その結果を表す PreparedStatementオブジェクトを入手している.
  • そのPreparedStatementオブジェクト (変数 stmt1) はその後の for文の中で繰り返し実行されている.
  • INSERT文中の ? はパラメータで,prepareした時点では値が決まっていない.実行する (PreparedStatementのexecute()メソッドを呼び出す)前に値をセットする.

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
...中略...
for (;;) {
    ...中略...
    System.out.print("酒名 = ");
    System.out.flush();
    String name = in.readLine();
    if (name.length() == 0)
        break;
    System.out.print("製造元 = ");
    System.out.flush();
    String make = in.readLine();
    ...中略...
}
  • データベースに挿入する値を手に入れている.この部分はJDBCプログラミングには関係ない.
  • readLine() でタイプインされる酒名,製造元の文字列を入手している.
  • for (;;) で無限ループを作っている.繰り返しの中で空の酒名が入力されると(if (...) break;により) ループから脱出するようになっている.

stmt1.setString(1, name);
stmt1.setString(2, make);
stmt1.execute();
  • PreparedStatementのパラメータの値として,酒名(変数 name)と製造元(変数 make)をセットしている.
    • setXxx(parIdx, val) (Xxx は String, Int, Double など型名, parIdx は1から始まるパラメータ番号,val はパラメータにセットする値) を呼び出すと,prepareStatement()メソッドで与えたSQL文中の?で表わされるパラメータに値を設定することができる.
    • ここでは,1番目のパラメータに酒名,2番目のパラメータに製造元を文字列として与えている.

Statement stmt2 = conn.createStatement();
ResultSet rs = stmt2.executeQuery("SELECT 名前, 製造元 FROM 酒");
while (rs.next()) {
    String name = rs.getString(1);
    String make = rs.getString(2);
    System.out.println(name + ", " + make);
}

最後にレコードの検索・取得で示した方法で,酒テーブルのすべてのレコードを列挙してプリントアウトしている.

個人用ツール
名前空間

変種
操作
案内
ツールボックス