JDBCいちから覚えなおし

Last-modified: 2007-12-15 (土) 00:12:46

担当者メモ

JDBCとは

JavaからDBに接続するためのAPI。
DBごとに作りは違うが、仕様が決まっているので
開発者は中身を意識することなく利用できる。

JDBC主要クラス

Connection…データベースとの接続を管理する
Statement…SQL文を実行する
PreparedStatement…パラメータ付きSQL文を実行する
ResultSet…SQLの実行結果を管理する

主要クラスの役割

Connection
 ・DBにアクセスするための接続を管理する(setAutoCommitメソッド)
 ・トランザクションの制御(commitメソッド、rollbackメソッド)
 ・SQL文を管理するオブジェクトを生成(createStatementメソッド、prepareStatementメソッド)

Statement
 ・SQL文の実行(executeQueryメソッド、executeUpdateメソッド)

PreparedStatement
 ・プリペアードステートメントのSQL文に値をセットする(setIntメソッド、setStringメソッド等)
 ・SQL文の実行(executeQueryメソッド、executeUpdateメソッド)

ResultSet
 ・SQL実行結果を管理する(nextメソッド、getStringメソッド等)

クラスの関連

{[zoom],}

練習

実際にデータベースを構築し、JDBCを用いてSQL文を実行してみましょう。
データベース環境の構築には「HSQLDB」を使用し、EclipseのJavaアプリケーションから
接続します。

HSQLDBの環境構築

・HSQLDBの入手
  下記ページより最新のバージョンをダウンロード
  http://sourceforge.net/project/showfiles.php?group_id=23316
  (2007/11/28現在の最新Verは hsqldb_1_8_0_9.zip )

 

・ファイルの解凍、展開
  ダウンロードしたzipファイルを解凍し、任意のフォルダに展開
  (例 C:\hsqldb\)

 

・動作確認
  MS-DOSプロンプトを開いてHSQLDB展開フォルダ配下のdataフォルダに移動し、
  次のコマンドを実行してHSQLDBのサーバを起動します。

C:\hsqldb\data> java -cp ..\lib\hsqldb.jar org.hsqldb.Server -database testdb

    ※dataフォルダ内に上記コマンドを実行するバッチファイルを作成しておくと
     今後の起動が楽になります。

 

  もう一つMS-DOSプロンプトを開き、HSQL Database Manager(管理ツール)を起動します。

C:\hsqldb\data> java -cp ..\lib\hsqldb.jar org.hsqldb.util.DatabaseManager -url jdbc:hsqldb:hsql://localhost

    ※上記コマンドもバッチファイルを作成しておくと楽になります。

 

・Eclipseの設定

  新規に動的Webプロジェクトを作成
  HSQLDB展開フォルダ配下のlib\hsqldb.jarを、作成したプロジェクトのWebContent/WEB-INF/libにコピー

 

事前準備

HSQLDBにサンプル用のテーブルを作成します。
次のSQL文をHSQL Database Managerのテキストボックスに入力して「Execute」ボタンをクリックしてください。

CREATE TABLE JRTRAIN ( DESIGN CHAR(20) PRIMARY KEY, LINE CHAR(20), TYPE CHAR(20), RANK INT );

メニューバーの「View」-「Refresh Tree」をクリックすると、左側のツリー上に作成したテーブルが表示されます。
続けて、作成したテーブルにデータを追加していきます。
次はSQL文をファイルから取り込んでみましょう。メニューバーの「File」-「Open Script...」をクリックして、E217.sql
(勉強会の当日に配布します)を選択して実行します。

実行したら、データが追加されているかを次のSELECT文で確認してみましょう。

SELECT * FROM JRTRAIN;

E217系の車両形式が7レコード表示されれば、データは正常に追加されています。

単純な検索

それでは、Javaからデータベースに接続してみましょう。まずは簡単な検索処理から行います。
srcフォルダに次のjavaファイルを作成してください。

作成したら、ナビゲーターからファイルを右クリックして「実行(R)」-「Javaアプリケーション」を選択して
検索を実行します。

コンソールにヘッダー+付随車3レコードが表示されれば、HSQLDBのJDBCドライバのロード・DBへの
アクセスは正常に出来ています。

 

ここで、鉄道に詳しい貴女ならDBの内容に誤りがあることに気づくでしょう。そう、グリーン車である
サロE217系・サロE216系は2等車なのにも関わらず、DBには等級が「3」と登録されています。
早速この誤りを次項で修正しましょう。

更新

トランザクションを意識しない更新

「とらんざくしょん?何それ?」という御方も居るかもしれませんが、まずは単純にUPDATE文を発行する
次のjavaファイルを実行してみましょう。

コンソールに「UPDATE文を実行しました。」と表示たら、HSQL Database Managerから再び全件検索の
SELECT文を実行してください。DBの内容が更新されているのが判ると思います。
が、ちょっと変です。「0等車」なんて存在しません。先ほど実行したSimpleUpdateTrain.javaのソースを
見直してみると、UPDATE文で変更箇所の指定が「RANK=0」となっています。記述を誤ったまま更新して
しまったんですね。

 

趣味で管理しているDBの更新であれば「あ、間違ってたから今修正しよう」ということでも構いませんが、
商用の業務DBで日中はサービス提供、夜間にDB更新するといった様な環境ですと、そうもいきません。
このような更新内容の指定誤りや、SQLの実行中にハードウェア障害などで更新処理が半端に
終わってしまった時などのために、「一つの処理単位(トランザクション)の最中に、不正な更新が
行われたり処理自体が正常に行えなかったときは、DBへ反映させずにキャンセルする」という
機能(トランザクションモード)があります。
先ほどの誤った更新内容を、トランザクションモードで更新し直してみましょう。

トランザクションを意識した更新(commit/rollback)

前項のjavaファイルに、トランザクションモード開始の宣言文・不正データのチェック・commit/rollbackの
実行を追加した次のjavaファイルを実行してみてください。

コンソールに「commitしました。DBが更新されました。」と表示されたら、再度HSQL Database Manager
からテーブルを全件検索してみましょう。グリーン車の等級が正しく「2」に更新されていますね。

 

今度は、commitされずにrollbackされた時の動きを確認しましょう。先ほどのjavaファイルを用いて、
等級を「4」に変更するようSQL文を書き換えて再度実行してみます。
コンソールに「rollbackしました。DBは更新されません。」と表示されました。他の出力内容を見ると、不正
データのチェックを行うif文も誤りを検出した時の分岐を通っているのが判ります。
これで本当にDBが更新されないまま終わっているのか、HSQL Database Managerから確認しましょう。
見ると、グリーン車の等級は先ほどcommitされた時点の等級「2」のままです。

 

このように、DBへ即座に更新をかけず直前にチェックを行い、不正なデータがあったり予期せぬ状態と
なっていたら後戻りする仕組みを設けることが出来ます。

動的な検索(PreparedStatement)

「単純な検索」の項目では、発行するSQL文をexecuteQueryメソッドの引数としてベタ書きしていました。
しかし、この書き方では「テーブル名だけ(または検索条件だけ)が異なるSQLを複数発行する」といった
処理を行いたいときに、発行するSQLの数だけクラスを作成したり一旦実行してからベタ書き部分を
書き換えて再コンパイル・実行したりと、効率が良くありません。
そんな時に、このPreparedStatementを利用します。

 

次のステップへ進む前に、テーブルのデータを少し増やしましょう。HSQL Database Managerから211.sql
(勉強会の当日に配布します)をスクリプトとして取り込み、実行しておいてください。

検索

次のjavaファイルを作成し、実行してください。

コンソールにSQLの実行結果が3回出力されましたでしょうか。
javaのソースに目を移しましょう。mainメソッドの中に、それぞれ異なる引数でprepExecQueryメソッドを
3回呼び出しています。実は、ここで渡している2つの引数がPreparedStatementへセットするパラメータの
値となっています。

 

続けてprepExecQueryメソッドの中を追っていきましょう。PreparedStatement型の変数にSQL文を代入
している箇所があります。よく見ると、「?」となっている部分があります。でもSQLにそんな構文はありません。
なんでしょう?
これは、PreparedStatementオブジェクトを生成するときにパラメータ化させたい部分を指定するのが、この
クエスチョンマークとなります。今回のサンプルコードでは「?」を2箇所指定していますね。

 

そのすぐ下の行で、パラメータへの値のセットをしています。
1つめのパラメータ(TYPE=?)はCHAR型のカラムなので、セットしたい値は文字列です。なので、メソッドの
仮引数paramStrはString型を指定しています。そして、setStringメソッドを使用して「1番目のパラメータに
paramStrの値(文字列)をセットする」という処理をしています。
2つめのパラメータ(RANK=?)はINT型のカラムなので、セットしたい値は整数です。これも、一つ目の
パラメータと同じように仮引数paramIntをInt型で指定し、今度はsetIntメソッドを使用して「2番目のパラメータ
にparamIntの値(整数)をセットする」という処理になっています。
パラメータセットの後は、executeQuery()メソッドの実行、ReaultSet.next()メソッドでSQL実行結果の
繰り回し表示と処理が続いています。

 

このように、クラスを複数作成したりSQL文を何度もベタ書きしなくてもパラメータを渡す処理だけを追記したり
書き換えるだけで、その値がセットされたSQL文を実行することができます。

更新

前項の検索結果を見て「東海道線では使われてない車両があるわ!」と気付いた貴女、お目が高い。
クモロ211系およびモロ210系は「スーパーサルーンゆめじ」の車両で、主に団体・イベント用に用いられて
いる車両であり普段の走行路線は東海道線ではなく瀬戸大橋線になります。しかも、無礼なことに等級が
また間違っています。早速この誤りを修正しましょう。

 

次のjavaファイルを作成し、実行してください。

コンソールからの入力値による検索

 

JDBCいちから覚えなおし は凍結されています。