連載
» 2001年06月12日 00時00分 公開

快速MySQLでデータベースアプリ!(8):Servlet/JSP+MySQLでアプリケーションサーバ その1 (2/3)

[鶴長鎮一,MySQLユーザ会]

Javaアプリケーションのコーディング

JDBCドライバのロードとMySQLサーバへの接続

 では、JDBCドライバをロードしてMySQLサーバへ接続するサンプルを見てみましょう(リスト1)。

 1、2行目でJDBC APIを使用するためにjava.net.*とjava.sql.*をインポートし、

import java.net.*;
import java.sql.*;

7〜11行目で必要な値の宣言を行います。

String server   = "localhost"; //MySQLサーバ
String db       = "ATMARKIT";  //
String user     = "test";      //ユーザー名
String pass     = "test2001";  //パスワード
String url      = "jdbc:mysql://" + server + "/" + db;

 11行目の、サーバの単純なURLは下記のように定義されます。

jdbc:<サブプロトコル名>://<サブネーム>

 一般的にホームページのアドレスは「http://www.mysql.gr.jp」のように「プロトコル名://サーバのアドレス」で構成されるのに対し、JDBC APIを使ってデータベースに接続するにはサブプロトコルが必要になります。このサブプロトコルはJavaSoftから一意に与えられており、MM.MySQL JDBCドライバの場合は「mysql」がサブプロトコルになります。

 次にMM.MySQL JDBCドライバをロードします(15行目)。

Class.forName("org.gjt.mm.mysql.Driver");

 準備が整ったところでDriverManagerのConnectionメソッドに、URL、ユーザー名、パスワードを引数として渡し、MySQLサーバと接続します(18行目)。

con = DriverManager.getConnection(url,user,pass);

 MySQLサーバに対するすべての操作が終わったところで接続を解除します(23行目)。

con.close();

 ではサンプルをコンパイル、実行してみましょう。Sample1.javaリスト1)を保存したディレクトリで下記のようにします。

$ $JAVA_HOME/bin/javac Sample1.java

 コンパイルが成功した後、Sample1.classファイルができていることを確認したら、上のディレクトリに先ほど展開してできたmysql.jarをコピーして実行します。

$ cp mm.mysql-2.0.4/mysql.jar .
$ $JAVA_HOME/bin/java -classpath mysql.jar:. Sample1

 MM.MySQL JDBCドライバを参照するため、javaコマンドに-classpathオプションを使ってmysql.jarファイルをclasspathに追加しています。ここで重要なのは、-classpathオプションを指定することです。暗黙的なclasspathである“.”(カレントディレクトリ)がclasspathから外れてしまうのを防ぐことです。そのため、

-classpath mysql.jar:.

とすることで、mysql.jarとカレントディレクトリを明示的にclasspathに追加します。成功していれば「接続成功です!」と表示されます。

レコードの挿入

 では次に、実際にMySQLサーバに対し「INSERT」を行ってみましょう(リスト2)。

 JDBCを使ってクエリーを作成するには、まずStatementオブジェクトを作成する必要があります(21行目)。

Statement stmt = con.createStatement();

 StatmentクラスのexecuteUpdate()メソッドにSQL文を渡すことでINSERT、UPDATE、DELETEEなど、SELECT以外のクエリーを実行できます(23行目)。

stmt.executeUpdate(sql_str);

注:SQL文中に「'」「"」「\」を含ませる場合はエスケープ文字を用いて「\'」「\"」「\\」とします。


 ではコンパイルと実行です。Sample2.javaリスト2)を保存したディレクトリで下記のようにします。

$ $JAVA_HOME/bin/javac Sample2.java
$ $JAVA_HOME/bin/java -classpath mysql.jar:. Sample2

 「レコードの挿入成功です!」と表示されれば成功です。また本当にデータが挿入されているか下記の手順で確かめてみましょう。

$ mysql ATMARKIT
mysql> select * from list;
+----+-------+--------------------------+
| id | name  | memo                     |
+----+-------+--------------------------+
|  1 | 1st   | memo 1st                 |
|  2 | 2nd   | 2nd trial                |
+----+-------+--------------------------+
2 rows in set (0.01 sec)

漢字の対応

 MySQLは多くの方の努力により、EUCやシフトJISなどのマルチバイト文字に対応しています。一方、Java内部ではUnicodeとして文字を扱い、入出力は実行環境のfile.encodingに左右されます。そのため、Windows 95/98/2000/NTではマルチバイトを含んだSQL文はシフトJISとして実行され、LANGがja_JP.eucJPにセットされているLinuxではEUCとして実行されます。Javaアプリケーションを実行する際に「java -Dfile.encoding=EUC_JP」などとして明示的に指定することも可能ですが、MM.MySQL JDBCドライバはURLにcharacterEncodingパラメータを指定することで、文字列を任意のコードとして扱えます(リスト3)。

 リスト2リスト3では、11行目が異なっていることが分かるかと思います。

String url      = "jdbc:mysql://" + server + "/" + db;
リスト2の11行目
String url      = "jdbc:mysql://" + server + "/" + db + "?useUnicode=true&characterEncoding=EUC_JP";
リスト3の11行目
jdbc:mysql://<MySQLサーバ名>:<ポート番号>/<データベース名>?useUnicode=true&characterEncoding=<サーバの文字コード>
characterEncodingを使った場合の書式

注:MySQLサーバがデフォルトの3306ポートで起動しているなら:<ポート番号>は省略できます。


●characterEncodingの例

[MySQLサーバがEUCで起動している場合]

jdbc:mysql://<MySQLサーバ名>:<ポート番号>/<データベース名>?useUnicode=true&characterEncoding=EUC_JP

[MySQLサーバがシフトJISで起動している場合]

jdbc:mysql://<MySQLサーバ名>:<ポート番号>/<データベース名>?useUnicode=true&characterEncoding=SJIS

注:characterEncodingパラメータは同時に「useUnicode=true」の指定が必要です。


 MM.MySQL JDBCでは、上記以外にもURLにパラメータを加えることでさまざまな値を調整できます。

変数 用途 デフォルト値
user 接続時のユーザー名 なし
password 接続時のパスワード なし
autoReconnects データベースとの接続が失われた場合、再接続を試みるかどうか(true/false) false
maxReconnects autoReconnectsが選択されている場合、再接続を何回まで行うか 3
initialTimeout autoReconnectsが選択されている場合、再接続までの待ち受け時間(秒数) 2
maxRows データベースサーバから受け取る最大レコード数(すべて受け取る場合は0) 0
useUnicode 文字列を扱う際、Unicode変換を行うかどうか(true/false) false
characterEncoding 文字コード変換を何で扱うか(useUnicodeが選択されている必要あり) なし
表 MM.MySQL JDBCのURLパラメータ

 URLの指定は、下記の要領になります。

jdbc:mysql://<MySQLサーバ名>:<ポート番号>/<データベース名>?<変数1=値1>&<変数2=値2>&...

 では、漢字を含んだINSERTクエリーを実行してみましょう。Sample3.javaリスト3)を保存したディレクトリで下記のようにします。

$ $JAVA_HOME/bin/javac Sample3.java
$ $JAVA_HOME/bin/java -classpath mysql.jar:. Sample3

 「漢字を含んだレコードの挿入成功です!」と表示されれば成功です。

レコードの抽出

 次はSELECTクエリーをJavaアプリケーションで実行してみましょう(リスト4)。

 リスト2と同様にStatementオブジェクトを作成します(21行目)。SELECTクエリーを実行するには、先ほどのexecuteUpdate()メソッドではなく、executeQuery()メソッドを呼び出し、戻り値にResultSetオブジェクトを受け取ります(25行目)。

ResultSet rs = stmt.executeQuery(sql_str);

 ResultSetオブジェクトのnext()メソッドの戻り値がfalseになるまでgetXX()メソッドに該当カラムのカラム番号を引数に渡し、処理を行います(28〜36行目)。

while(rs.next()){
    int id = rs.getInt("id");
    String name = rs.getString("name");
    String memo = rs.getString("memo"); 
 
    System.out.println("-------" + id + "---------");
    System.out.println("name:" + name);
    System.out.println("memo:" + memo);
} 

注:カラム番号ではなく、カラム名を引数に渡すこともできます。


 ResultSetオブジェクトには、各レコードの型に対応して下記のようなデータの取得方法が用意されています。

get系メソッド 得られるJavaの型
getAsciiStream InputStream
getBigDecimal BigDecimal
getBinaryStream InputStream
getBoolean boolean
getByte byte
getBytes byte[]
getDate sava.sql.Date
getDouble double
getFloat float
getInt int
getLong long
getObject java.lang.Object
getShort short
getString String
getTime java.sql.Time
getTimestamp java.sql.timestamp
getUnicodeStream InputStream

 では、実行してみましょう。Sample4.javaリスト4)を保存したディレクトリで下記のようにします。

$ $JAVA_HOME/bin/javac Sample4.java
$ $JAVA_HOME/bin/java -classpath mysql.jar:. Sample4

 先ほど登録したレコードも含めて結果が表示されると思います。

-------1---------
name:1st
memo:memo 1st
-------2---------
name:2nd
memo:2nd trial
-------3---------
name:3番目
memo:3番目のテスト

 次回は、今回作成したプログラムをServlet化してWebブラウザから使えるようにしたいと思います。また、Servletを実行するにはApacheに加えてTomcatというJava実行環境が必要になります。そこでTomcatの設定についても紹介します。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。