Powered by SmartDoc

JDBC (1)

JDBCプログラミングの基本パターン

JDBCは、Javaを使ってリレーショナルデータベースを利用するためのAPIです。

JDBCを使ったプログラミングの基本パターンは、次の通りです。

ステップ1 データベースとの接続の確立
Connectionオブジェクトを取得します。
ステップ2 SQL文の実行
Statementオブジェクトを取得し、SQL文を実行します。
ステップ3 SQLの実行結果の処理
ResultSetオブジェクトからデータを取り出します。

では、サンプルを見てみましょう。このサンプルは、次のようなテーブルから、titleに"Java"という文字が含まれている本を検索して、タイトルを出力するプログラムです。

create.sql
create table books (
    ndc           varchar(10),
    tyosya_hyouji varchar(2),
    id            int,
    title         varchar(50),
    author        varchar(50),
    publisher     varchar(30),
    constraint pk_books primary key(id)
);
JDBCTest.java
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class JDBCTest {

    public static void main(String args[]) {
        try {
            // (1) データベースとの接続の確立
            Class.forName("org.hsqldb.jdbcDriver");
            String url = "jdbc:hsqldb:hsql://localhost";
            Connection con = DriverManager.getConnection(url, "sa", "");

            // (2) SQLの実行
            String selectStatement =
                "select title " +
                "from books where title like ?";
            PreparedStatement prepStmt =
                con.prepareStatement(selectStatement);
            prepStmt.setString(1, "%Java%");
            ResultSet rs = prepStmt.executeQuery();

            // (3) SQLの実行結果の処理
            while (rs.next()) {
                String title = rs.getString("title");
                System.out.println(title);
            }

            // (4) 後始末
            rs.close();
            prepStmt.close();
            con.close();

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

データベースとの接続の確立

まず最初のステップは、データベースとの接続を確立し、Connectionオブジェクトを得ることです。Connectionオブジェクトを取得する方法はいくつかあります。ここでは、最も一般的である、JDBCドライバをロードする方法について解説します。

JDBCドライバの利用

まず、JDBCドライバを利用する例です。JDBCドライバとは、データベース管理システム(DBMS)に固有の処理をまとめたものです。JDBCドライバもJavaで書かれており、通常はjarファイルにまとめられています。

 // (1) データベースとの接続の確立
 Class.forName("org.hsqldb.jdbcDriver");
 String url = "jdbc:hsqldb:hsql://localhost";
 Connection con = DriverManager.getConnection(url, "sa", "");

この例では、HSQLDBを使用しています。

1行目で、HSQLDB用のJDBCドライバをロードしています。2行目で、データベースのありかを示すURLを指定します。URLは、次のような構造になっています。

   jdbc:サブプロトコル:サブネーム

この例では、サブプロトコルが"hsqldb"で、サブネームが"hsql://localhost"になっています。

3行目で、データベースにアクセスするために必要なユーザ名・パスワードとURLを指定して、Connectionオブジェクトを取得しています。ここでは、ユーザ名"sa"で、パスワードは空になっています。

SQL文の実行

Statement

Connectionオブジェクトを取得したら、Statementを使ってSQLを実行します。

		// (2) SQLの実行
		String selectStatement =
				"select title from books";
		Statement stmt = con.createStatement();
		ResultSet rs = stmt.executeQuery(selectStatement);

Connectionオブジェクトから、Statementオブジェクトを生成します。Statementは、SQL文をデータベースに送るための入れ物のような役割を果たします。Statement#executeQueryメソッドによって、データベースにSQL文を送ります。

PreparedStatement

PreparedStatementはStatementを継承したものです。

サンプルを見てみましょう。

        String insertStatement =
            "insert into books values ( ? , ? , ? , ? , ? , ? )";
        PreparedStatement prepStmt = 
            con.prepareStatement(insertStatement);

        prepStmt.setString(1, ndc);
        prepStmt.setString(2, tyosya_hyouji);
        prepStmt.setString(3, id);
        prepStmt.setString(4, title);
        prepStmt.setString(5, author);
        prepStmt.setString(6, publisher);

        int result = prepStmt.executeUpdate();
        prepStmt.close();

Statementとの違いは、大きく分けて2つあります。

1つめは、SQL文が渡されるタイミングです。StatementではexecuteQueryメソッドを実行するときにSQL文が渡されます。それに対して、PreparedStatementではオブジェクトが生成されるときにSQL文が渡されます。PreparedStatementでは、SQL文はプリコンパイルされ、データベースで高速に処理されます。

もう1つの違いは、渡されるSQL文です。このサンプルでは、

        "insert into books values ( ? , ? , ? , ? , ? , ? )";

というように、クエスチョンマークが6つ並んでいます。これは、SQLの文法にはない形です。このクエスチョンマークの部分には、PreparedStatement#setXXXというスタイルのメソッドを使って、データを設定します。例えば、PreparedStatement#setStringというメソッドは、クエスチョンマークの部分に文字列型のデータを挿入します。このメソッドには2つの引数があり、はじめの引数にはクエスチョンマークの順番を与え、2つめの引数には挿入したいデータを与えます。

        prepStmt.setString(3, id);

この部分は、3番目のクエスチョンマークにidというString型のデータを与えることを意味します。

StatementよりもPreparedStatementを利用することで、より柔軟なプログラムを作れます。

データベースの検索と更新

StatementやPreparedStatementでは、SQLのselect文を実行するとき、executeQueryメソッドを使います。検索結果として、ResultSetが返されます。

        ResultSet rs = stmt.executeQuery(selectStatement);

また、insert, update, deleteのような、データベースの更新を行う処理には、executeUpdateメソッドを使います。更新された行数が返されます。

        int result = prepStmt.executeUpdate();

SQLの実行結果の処理

SQLのselect文による検索結果は、ResultSetオブジェクトで返されます。

		// (3) SQLの実行結果の処理
		while (rs.next()) {
			String title = rs.getString("title");
			System.out.println(title);
		}

ResultSetには、複数の行のデータが含まれています。rs.next()メソッドの繰り返しによって、次々と行を処理していきます。

        String title = rs.getString("title");

この部分では、1行分の検索結果のうち、"title"という項目のデータを、String型として取り出しています。

プログラムのコンパイルと実行

JDBCを使ったプログラムでは、JDBCドライバを読み込んでいます。そのため、JDBCドライバがある場所を指定しなければ、プログラムのコンパイルも実行もできません。そこで、JDBCドライバがまとめられているjarファイルの場所を、「クラスパス」で指定します。

HSQLDBをインストールしているフォルダをHSQLDB_HOMEという環境変数に設定しています。

最初に、コンパイルの方法です。

D:\Home>javac -classpath %HSQLDB_HOME%\lib\hsqldb.jar;. JDBCTest.java \
    (1行で入力してください)

javacコマンドにclasspathオプションを指定しています。HSQLDBのJDBCドライバは、%HSQLDB_HOME%\libディレクトリにあるhsqldb.jarに含まれているので、このファイルをclasspathに指定します。

次に、実行方法です。データベースを立ち上げている必要があります。

D:\Home>java -classpath %HSQLDB_HOME%\lib\hsqldb.jar;. JDBCTest