4 Java 開発download.microsoft.com/.../4-JavaExplanation.pdfJDBC API は、次に挙げる Java...

37
4 Java 開発 (Microsoft JDBC Driver 2.0 使用 )

Transcript of 4 Java 開発download.microsoft.com/.../4-JavaExplanation.pdfJDBC API は、次に挙げる Java...

4 - Java 開発

(Microsoft JDBC Driver 2.0 使用)

1

このドキュメントに記載されている情報 (URL 等のンターネット Web サトに関する情報を含む) は、将来予告なしに変更するこ

とがあります。このドキュメントに記載された内容は情報提供のみを目的としており、明示または黙示に関わらず、これらの情報につ

いてマクロソフトはいかなる責任も負わないものとします。

お客様が本製品を運用した結果の影響については、お客様が負うものとします。お客様ご自身の責任において、適用されるすべての著

作権関連法規に従ったご使用を願います。このドキュメントのいかなる部分も、米国 Microsoft Corporation の書面による許諾を受け

ることなく、その目的を問わず、どのような形態であっても、複製または譲渡することは禁じられています。ここでいう形態とは、複

写や記録など、電子的な、または物理的なすべての手段を含みます。

マクロソフトは、このドキュメントに記載されている内容に関し、特許、特許申請、商標、著作権、またはその他の無体財産権を有

する場合があります。別途マクロソフトのラセンス契約上に明示の規定のない限り、このドキュメントはこれらの特許、商標、著

作権、またはその他の無体財産権に関する権利をお客様に許諾するものではありません。

別途記載されていない場合、このソフトウェゕおよび関連するドキュメントで使用している会社、組織、製品、ドメン名、電子メー

ル ゕドレス、ロゴ、人物、出来事などの名称は架空のものです。実在する会社名、組織名、商品名、個人名などとは一切関係ありませ

ん。

© 2010 Microsoft Corporation. All rights reserved.

Microsoft、MSDN、SQL Server、Windows Vista は、米国 Microsoft Corporation の米国およびその他の国における登録商標また

は商標です。記載されている会社名、製品名には、各社の商標のものもあります。

2

目次

1 本書の概要 ................................................................................................................................ 3

2 事前に準備する環境 .................................................................................................................. 3

2.1 必要なソフト環境 ........................................................................................................................ 3

2.2 データベースの作成 .................................................................................................................... 3

3 JDBC とは ................................................................................................................................ 4

3.1 JDBC ゕーキテクチャ ................................................................................................................. 4

3.2 JDBC API について ..................................................................................................................... 5

3.2.1 パッケージ構成 ............................................................................................. 5

3.2.2 データ型 ...................................................................................................... 6

4 JDBC プログラミング .............................................................................................................. 7

4.1 データベースとの接続の確立 ...................................................................................................... 7

4.1.1 接続のための情報を準備 ................................................................................. 7

4.1.2 接続の確立 ................................................................................................... 8

5 まずは実行してみよう ............................................................................................................... 9

5.1 新規 Java プロジェクトの作成と設定 ....................................................................................... 9

5.2 新規クラスを作成 ...................................................................................................................... 12

5.3 サンプル プログラムの実行 ...................................................................................................... 13

5.3.1 SQL Server の環境確認 ............................................................................... 13

5.3.2 プログラムの実行 ........................................................................................ 14

6 データの操作方法 .................................................................................................................... 16

6.1 SQL の実行方法 ........................................................................................................................ 16

6.1.1 Statement オブジェクトの種類と生成方法 ...................................................... 16

6.2 問い合わせの方法 ...................................................................................................................... 17

6.2.1 結果セットの処理方法 .................................................................................. 19

6.2.2 カーソル操作 .............................................................................................. 19

6.2.3 バンド変数を使用した問い合わせ ................................................................. 21

6.3 データの更新方法 ...................................................................................................................... 23

6.4 トランザクションの制御 ........................................................................................................... 24

6.4.1 自動コミットモードを OFF に設定する。 ........................................................ 25

6.4.2 トランザクションの開始と完了 ...................................................................... 25

7 ちょっと高度なプログラミング................................................................................................ 27

7.1 ResultSet を使った更新処理 .................................................................................................... 27

7.2 DataSource オブジェクトを使った接続 ................................................................................. 30

7.3 JDBC ドラバーのログを活用する ......................................................................................... 35

8 おわりに ................................................................................................................................. 35

9 参考文献 ................................................................................................................................. 36

3

1 本書の概要

本書は、Java プログラミングの基礎と SQL を理解されていて、JDBC (Java DataBase Connectivity) に

よるリレーショナル データベースのデータ操作をはじめて経験される方や、JDBC プログラミングを始めて、

比較的に日の浅い方に向けてまとめられています。

2 事前に準備する環境

2.1 必要なソフト環境

本書の内容を読み進めるにあたり、下記の環境が必要になります。

OS (以下のいずれか)

Windows XP Professional SP3 以降

Windows Vista®

ソフトウェア(以下のすべて)

Microsoft® SQL Server® 2008 Enterprise Edition

Microsoft SQL Server JDBC Driver 2.0

http://www.microsoft.com/downloads/details.aspx?displaylang=ja&FamilyID=99b21b65-e98f

-4a61-b811-19912601fdc9

JDBC ドラバーの INSTALL フゔルの推奨に従い、Program Files デゖレクトリに展開します。

JDK 6 Update 17 またはそれ以降

Eclipse IDE for Java EE Developers

http://www.eclipse.org/downloads/

日本語化する際は、Babel 等を適用(http://www.eclipse.org/babel/)

2.2 データベースの作成

本書に掲載のサンプルコードを実行するにあたり、サンプルのデータベース環境が必要です。下記の手順で

作成しておいてください。

サンプル コード一式の中に、データベースの DDL も同梱しています。事前にこの DDL を使って

サンプルのデータベースを作成してください。

DDL のフゔルは、sample_code.zip の中の「SmapleProject\sq\DDL.sql」です。

本書で解説する JDBC 接続は TCP 接続を使います。SQL Server でローカル ホストからの TCP 接

続を、ポート番号 1433 で受け付けるよう設定してください。

4

3 JDBC とは

JDBC とは、「Java プログラムから様々なデータにゕクセスするための汎用的な API」のことを言います。

つまり、リレーショナル データベースやスプレッドシート、フラット フゔルなどの様々なデータソース

に対して、JDBC という一つの API を通じて操作できる事を概念としています。

ここでは、JDBC を利用したプログラミングを行うにあたり、前提として知っておくべき事柄について、解

説します。

3.1 JDBC アーキテクチャ

先ほど、JDBC とは「Java プログラムから様々なデータにアクセスするための汎用的な API」であると説

明しました。しかし、リレーショナル データベースとフラット フゔルでは、データ構造が異なり、一方

は RDBMS が管理するデータで、もう一方は OS が管理するデータです。なぜ汎用的な操作が可能なので

しょうか。それは JDBC のゕーキテクチャを眺めることで理解できるでしょう。JDBC のゕーキテクチャは

次の図のような構成になっています。

JDBC ドラバーとは、ゕプリケーションに代わって、データソースに直接ゕクセスするためのコンポーネ

ントです。先に疑問点として挙げたとおり、データソースが異なれば、その管理方法も異なり、さらにゕク

セス方法も異なる事が少なくありません。そのため、それら多種多様なデータソースを操作するための JDBC

ドラバーは、データソースの種類に応じて、それぞれ専用のソフトウェゕとして提供されます。そして、

それを JDBC という API を介す事により、汎用的なンタフェースを提供しています。JDBC ドラバー

マネージャーの役割は、ゕプリケーションが要求するデータソースの種別を認識し、そのデータソースにゕ

クセスするための JDBC ドラバーを見つけ出し、ゕプリケーションと該当の JDBC ドラバーとの間を

橋渡しする事を主としています。

5

3.2 JDBC API について

JDBC API が提供する機能は、下記に挙げるとおり、大雑把ではありますが、通常の SQL で出来る事が基

本となっています。

① データソースとの接続の確立

② データソースへのクエリー及び更新文の送信

③ 実行結果の処理

少し蛇足しますが、厳密に述べると、JDBC API は単に共通なプログラミング ンタフェースを定義してい

るだけで、その仕様は JCP (Java Community Process) という国際的な標準化組織が標準化しています。

実際にデータソースへのゕクセス処理を行うのは、JDBC のンタフェースを介して呼び出される JDBC ド

ラバーの該当メソッドが行います。その JDBC ドラバーの実装は、通常、データベース ソフトを開発

する開発元が、データベース サーバーの開発と併せて実装します。

ンタフェース定義を標準化組織が行い、その実装をデータベース ソフトのベンダーという異なる組織が行

うわけですから、JDBC API に定義されているメソッドが、JDBC ドラバー側で実装されていない場合も

稀にあります。以上の事から、プログラム設計などの場面で、あるデータベース ソフトの JDBC ドラバ

ーを始めて使う場合は、この事を頭に置きながら事にあたるべきです。必ず使われるであろう機能は、さす

がに未実装のケースは無いと思いますが、比較的特殊な機能は実装されていない可能性があり得るという事

です。

3.2.1 パッケージ構成

JDBC API は、次に挙げる Java パッケージ群に納められており、JDBC を利用するプログラムは、これら

のパッケージをンポートする事になります。

① java.sql パッケージ- JDBS コゕ API

② java.sql パッケージ- JDBC 標準拡張機能 API

6

3.2.2 データ型

JDBC が SQL の型と対応付ける Java のデータ型について、これもデータベース ソフト毎に対応が異なり

ます。SQL Server 2008 の場合は下記の通りとなっています。

SQL Server 型 Java 言語型

bigint long

timestamp

binary byte[]

bit boolean

char String

decimal

money

smallmoney

java.math.BigDecimal

float double

int int

image

varbinary(max) byte[]

varchar(max)

text String

nchar String

nvarchar String

nvarchar(max)

ntext String

numeric java.math.BigDecimal

real float

smallint short

datetime

smalldatetime java.sql.Timestamp

varbinary

udt byte[]

varchar String

tinyint short

uniqueidentifier String

xml String

SQLXML

MSDN® より抜粋(http://msdn.microsoft.com/ja-jp/library/ms378878.aspx)

7

4 JDBC プログラミング

ここまでで、JDBC を使ってプログラミングする上で、事前に知っておくべき事柄について説明してきまし

た。続いて、JDBC の機能を利用するためのプログラミング方法について見ていきたいと思います。

「3.2 JDBC API について」の冒頭で挙げた JDBC が提供する機能に沿って、順に解説したいと思います。

本書では、SQL Server 2008 が管理するデータベースにゕクセスするためのプログラミング方法を解説し

ます。そのため、ここまでで使っていたデータソースという言葉を、少し狭義に変えて、データベースと呼

ぶ事にします。

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

データベースへの接続の確立には、二つの手順を踏む事になります。1 つは、「接続のための情報を準備する」

ことで、2 つ目は「接続の確立」です。

4.1.1 接続のための情報を準備

JDBC を利用してデータ ソースに接続するための情報は、URL で表現されます。URL と聞くと、http や

ftp のプロトコルを使った Uniform Resource Locator が思い浮かぶかと思いますが、まさにその事を指し

ています。URL のスキーマ部は通信プロトコルの種別を表す事になっており、それに続いて、ホスト名とリ

ソースへのパス情報を続けて指定します。JDBC の URL も同じような形式で表すことになっています。

JDBC URL の標準形式は、下記の通りとなっています。

jdbc:subprotocol:subname

jdbc は、http や ftp と同じくプロトコルを表し、固定で指定しなければなりません。

subprotocol は、ドラバー名を指定します。SQL Server の場合は固定で「sqlserver」になります。

subname には、データソースを特定するための情報を指定します。Subname は、JDBC ドラバー毎

に異なる書式になっていることがあるので、例えば、データベース サーバーを移行する場合などには注

意が必要です。

SQL Server の場合は、次の書式で指定します。

//[serverName[\instanceName][:portNumber][;property=value][;property=value]・・・]

serverName (省略可能) は、接続先のサーバーのゕドレスを指定する事になっており、FQDN や

IP ゕドレスを指定できます。

instanceName (省略可能) は、serverName 上にある接続先のンスタンスを指定します。省

略した場合は、既定のンスタンスへの接続が確立されます。

portNumber (省略可能) は、serverName 上で SQL Server が接続を受け付けるために使用して

いるポートを指定します。既定では 1433 です。既定のポートを使用する場合は省略し、その前

の ':' も省きます。名前付きンスタンスに接続するときに、ポート番号を省略すると、ポート番

号を決定するための通信が発生するため、接続時のパフォーマンスを考慮すると、ポート番号は明

示的に指定した方が良いようです。

8

property=value(省略可能)は、データベース サーバー固有の接続パラメータを指定可能にし

ています。プロパテゖ毎の区切り文字がコロン(:)ではなく、セミコロン(;)であることに注

意してください。これを間違えて、接続できないと騒いでいる人をたまに見かけます。SQL Server

JDBC Driver では、JDBC ドラバーの挙動に関して、より詳細な制御を可能とするパラメータが

用意されています。SQL Server の MSDN オンランには、用意されているパラメータの一覧が掲

載されていますので、詳しく知りたい方はそちらをご覧下さい。

http://msdn.microsoft.com/ja-jp/library/ms378988.aspx

ここで、SQL Server に接続するための JDBC URL のサンプルを下記に挙げます。

通常、データベースに接続するには、更にユーザのゕカウント情報が必要になりますが、これも URL に含

めて指定する事ができます。このときのサンプルは次のようになります。

ただし、URL にユーザのゕカウント情報を記述する事は、セキュリテゖの観点からお勧めしません。

4.1.2 接続の確立

ここまでで、データソースに接続するための情報として、JDBC URL が準備できました。次に、Java プロ

グラムを書いて、実際にデータベースに接続してみましょう。

データベースとの接続の確立は、java.sql.DriverManager クラスの getConnection() メソッドを使います。

最も簡単なコーデゖング例を下記のリストに示します。

1

2

3

4

5

6

7

8

9

package com.sample.jdbc;

import java.sql.DriverManager;

import java.sql.Connection;

import java.sql.SQLException;

public class SampleClass1 {

public static void main(String[] args) {

9

10

11

12

13

14

15

16

17

18

19

20

21

22

String url = "jdbc:sqlserver://localhost\\SampleDB:1433";

try {

Connection con = DriverManager.getConnection(url,

"sample_user", "sample_pass");

} catch(SQLException e) {

System.out.println("接続に失敗");

System.out.println("エラーコード=" + e.getErrorCode());

System.out.println("エラーメッセージ=" + e.getSQLState());

System.exit(1);

}

System.out.println("接続成功");

}

}

JDBC API のメソッドは、概して SQLException を throw します。上のコードでは SQLException を

キャッチして例外処理を行っています。

SQLException からは、エラーコードと、その意味を示すエラーメッセージを取得する事ができます。ゕプ

リケーションは、それらの情報を基に例外処理を実装する事ができます。

SQLException で用意されているメソッドを下記に説明します。(MSDN より抜粋)

getSQLState() は、例外の標準的な X/Open または SQL99 状態コードを返します。

getErrorCode() は、具体的なデータベース エラー番号を返します。

getMessage() は、例外の全文を返します。 エラー メッセージ テキストは問題について説明します。

そして、オブジェクト名のような情報のプレースホルダを含むことがよくあります。こうしたプレース

ホルダは、エラー メッセージが表示されるとき、その中に挿入されます。

5 まずは実行してみよう

さて、ここまで書いてしまうと、早速プログラムを実行したくなるのが、プログラマの性というもの。

データベースのテーブルへのゕクセス方法などは後回しにして、早速実行してみましょう。

プログラムの実行環境として、今回は、Eclipse IDE for Java EE Developers (以後 Eclipse と呼びます) を

使います。そこで、先に挙げたサンプルソースを Eclipse に入力しますが、手順は下記の通りとなります。

5.1 新規 Java プロジェクトの作成と設定

[ファイル]-[新規]-[Java プロジェクト] で SampleProject というプロジェクトを作成します。「新規

Java プロジェクト」ダゕログの「Java プロジェクトの作成」パネルで下記のように入力します。

10

「次へ」を選択し、「Java 設定」パネルに遷移します。

ここでは、JDBC ドラバーの jar フゔルを CLASSPATH に追加する必要がありますが、ドラバーの

所在は「<インストールディレクトリ>\ Microsoft SQL Server JDBC Driver\sqljdbc_2.0\jpn」です。

このデゖレクトリには、上図の通り sqljdbc.jar と sqljdbc4.jar の 2 つのフゔルがありますが、これ

らは下記に説明するとおりに使い分ける事になっています。

11

※SQL Server JDBC Driver 2.0 のドキュメントより抜粋

JDK6 は、JDBC4.0 という仕様のンタフェースを採用したバージョンで、それより前のバージョンの JDK

は、JDBC3.0 かそれ以前のンタフェースを採用しています。

今回は、JDK6 を使用しているので、ここでは sqljdbc4.jar を指定します。

実際の指定方法ですが、「Java 設定」パネルで「外部 JAR の追加...」ボタンを選択し、sqljdbc4.jar を

指定して下さい。

指定した後は、パネルの状態は次のようになっています。

「終了」ボタンを選択すると、SampleProject が作成されます。

12

5.2 新規クラスを作成

次に、SampleProject にサンプルソースを追加します。クラス名は、com.sample.jdbc.Smaple1.java

としてください。Eclipse 画面のパッケージ エクスプローラ-で、src を右クリックし、[新規]-[クラス]

を選択します。

すると、「新規 Java クラス」ダゕログが表示されるので、次の図の通り、パッケージ名に

com.sample.jdbc と、クラス名に Sample1 と入力し、「public static void main(String[] args)」

のチェック ボックスをオンにしてから「終了」ボタンを選択します。

13

作成されたソースフゔルの内容は、下記のようになっているので、確認してください。

ここに、次の図の通り、先ほどのサンプルコードを入力してください。

以上でプログラムの準備が整いました。

これを実行するにあたり、データベース側の準備ができているか、いま一度確認したいと思いますので、次

の手順で確認してください。

5.3 サンプル プログラムの実行

5.3.1 SQL Server の環境確認

申すまでもありませんが、このプログラムを実行するにあたって、接続先となる SQL Server に、データベ

ースを作っておく必要があります。本書では、SQL Server の操作の詳細については、触れませんので、「2.2

データベースの作成」で説明している通り、データベースを作成してください。

Server Management Studio を開いて、下図のように SampleDB というデータベースと、それにゕク

セス可能な sample_user というユーザが作成されていれば問題ありません。

14

以上のほかに、次の点も確認をお願いします。

(1) SQL Server のサービス

SQL Server のサービスが実行中かを確認してください。

(2) TCP 接続の許可

本書で解説する JDBC 接続は TCP 接続を使います。SQL Server でローカルホストからの TCP 接続

を有効にしているか確認してください。

5.3.2 プログラムの実行

ここまでできたら、プログラムを実行する準備が完了です。

では、Eclipse で実行してみてください。メニューから行う場合は、[実行]-[実行]を選択します。ツー

ルバーの [実行] ボタンでも結構です。

15

コンソールに、下記のように「接続成功」と表示されれば、正しく動作した事になります。もしも接続でき

ない場合は、SQL Server が接続を受け付ける設定ができているかなどを確認してください。MSDN の SQL

Server JDBC ドラバーのドキュメントには、接続できない場合の診断方法が掲載されています。こちらの

情報も活用してください。

http://msdn.microsoft.com/ja-jp/library/ms378845.aspx

ちなみに、このサンプルコードは少し行儀が悪いコードになっていて、プログラム終了前に接続を閉じるコ

ードが抜けています。切断のコード(18 行目)を加えると、下記の通りとなります。

1

2

3

4

5

6

7

8

9

10

11

package com.sample.jdbc;

import java.sql.DriverManager;

import java.sql.Connection;

import java.sql.SQLException;

public class Sample1 {

/**

* @param args

*/

16

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

public static void main(String[] args) {

String url = "jdbc:sqlserver://localhost\\SampleDB:1433";

try {

Connection con = DriverManager.getConnection(url,

"sample_user", "sample_pass");

System.out.println("接続成功");

con.close();

} catch(SQLException e) {

System.out.println("接続に失敗");

System.out.println("エラーコード=" + e.getErrorCode());

System.out.println("エラーメッセージ=" + e.getLocalizedMessage());

System.out.println("SQL STATE=" + e.getSQLState());

System.exit(1);

}

}

}

6 データの操作方法

続いて、データの操作方法、つまり SQL の実行方法について説明します。

6.1 SQL の実行方法

JDBC による SQL の実行には、Statement オブジェクトを使用します。Statement オブジェクトは SQL

文をモデル化したもので、参照系の SQL を実行する際に使用する executeQuery() メソッドと、更新系

の SQL を実行する際に使用する executeUpdate() メソッドが用意されています。executeQuery() メ

ソッドから返却される結果セットは、ResultSet オブジェクトとして返却されます。

① executeQuery()

参照系の SQL(SELECT) を実行する際に使用し、単一の結果セット (Resultset オブジェクト)

を返却します。

② excecuteUpdate()

更新系の SQL を実行する際に使用します。INSERT、UPDATE、または DELETE の各文、

および DDL 文(CREATE、DROP、ALTER など)を実行するために使用し、更新の影響を受け

た行数などの整数値を返却します。

次に、Statement ブジェクトの種類と生成方法に触れます。

6.1.1 Statement オブジェクトの種類と生成方法

Statement ブジェクトには、PreparedStatement ブジェクトと allableStatement ブジェクトがあり

ます。PreparedStatement ブジェクトはコンパル済みの SQL 文を含むもので、通常の SQL の実行に

17

はこちらを使用します。CallableStatement オブジェクトは、ストゕドプロシージャを呼び出す際に使用

されるものです。

Statement オブジェクトの種類

① PreparedStatement オブジェクト

通常の SQL を実行する場合に使用します。

② CallableStatement オブジェクト

ストゕドプロシージャを呼び出す際に使用します。

PreparedStatement オブジェクトと CallableStatement オブジェクトは、Statement ンタフェー

ス クラスを実装したクラスのオブジェクトになっています。

これらのオブジェクト (ンスタンス) は、Connection オブジェクトに生成を依頼することで得られます。

Connection オブジェクトで用意されている生成方法は下記の通りです。

Connection オブジェクトが提供する Statement オブジェクトの生成方法

① prepareStatement()

PreparedStatement オブジェクトを返却します

② prepareCall()

CallableStatement オブジェクトを返却します。

③ createStatement()

用意されている引数の指定によって、PreparedStatement オブジェクトや CallableStatement

オブジェクトを返却します。

以上を踏まえて、実際の SQL 文を使ってこれらの API を試してみましょう。

6.2 問い合わせの方法

本書の冒頭で用意をお願いしていたデータベースに問い合わせを行う、簡単なプログラムを書いてみましょ

う。PRODUCTS_TABLE から、PRODUCT_ID で昇順にソートされた全ての行を取得し、標準出力に出

力するプログラムを書いてみます。問い合わせ処理の概要を先に説明しますと、下記の手順で処理を行いま

す。

① Connection オブジェクトから Statement オブジェクトを取得 (22 行目)

② Statement オブジェクトの executeQuery() メソッドで SQL を実行 (23 行目)

③ executeQuery() メソッドから返された Resultset オブジェクトを使い、標準出力に出力する

(25~31 行目)

「5.3.2 プログラムの実行」で使用した Sample1 クラスを改良して、PRODUCTS_TABLE テーブルの全

レコードを抽出するコード(Sample2)が下記になります。

1

2

3

4

package com.sample.jdbc;

import java.sql.DriverManager;

import java.sql.Connection;

18

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import java.text.DecimalFormat;

public class Sample2 {

/**

* @param args

*/

public static void main(String[] args) {

String url = "jdbc:sqlserver://localhost\\SampleDB:1433";

Connection con = null;

try {

con = DriverManager.getConnection(url, "sample_user", "sample_pass");

System.out.println("接続成功");

Statement stmt = con.createStatement();

ResultSet r = stmt.executeQuery("SELECT * FROM PRODUCTS_TABLE ORDER BY ID");

while( r.next() ){

System.out.print(r.getString("NAME"));

System.out.print("(単価"+

DecimalFormat.getCurrencyInstance().format(

Integer.valueOf(r.getString("PRICE")))+"、");

System.out.println("在庫"+r.getString("STOCK")+"個)");

}

r.close();

con.close();

} catch(SQLException e) {

System.out.println("=========================================");

System.out.println("エラーコード=" + e.getErrorCode());

System.out.println("エラーメッセージ=" + e.getLocalizedMessage());

System.out.println("SQL STATE=" + e.getSQLState());

System.out.println("=========================================");

System.exit(1);

}

}

}

このプログラムを実行した結果、コンソールに下記のように表示されるはずです。

19

6.2.1 結果セットの処理方法

ここで、ResultSet オブジェクトについて説明します。サンプルコード Sample2 の 25 行目では、

ResultSet オブジェクトの next() メソッドを使っています。これは、結果セットに対して、カーソルの移

動を行っていることになります。そして、26 行目から 30 行目で、getString() メソッドを使って、カラ

ムの値を取得しています。カラムの取得には、カラム名を使用できます。最後に使い終わった ResultSet

オブジェクトを、32 行目でクローズしています。

getString() メソッドのほか、データの種類により、下記に挙げるメソッドも用意されていますが、全ては

挙 げ ら れ な い の で 、 詳 し く は Java の API リ フ ゔ レ ン ス を 是 非 ご 覧 に な っ て 下 さ い 。

6.2.2 カーソル操作

次に ResultSet オブジェクトで提供されているカーソルの操作方法について、その使い方を説明します。

カーソルは、結果セット内での現在行を指し示すもので、結果セット内でのカーソルの移動や修正の操作を

20

可能とする機能が付随しますが、データベース サーバーによりサポートされるカーソルの種類は異なります。

本書ではその説明を割愛しますが、本書で使っている SQL Server でサポートされるカーソルは豊富にあり

ますので、MSDN で確認してみてください。

(http://technet.microsoft.com/ja-jp/library/ms378405.aspx) ResultSet オブジェクトに用意され

ているカーソル操作のメソッドは下記の通りで、処理の必要に応じて使い分けます。

以上のメソッドで、カーソル移動用メソッドを利用するために、前準備として一つ忘れてはならない事があ

ります。それは、Connection オブジェクトの createStatement() で Statement オブジェクトを取得

する際に、ResultSet オブジェクトのタプを指定する必要があるという事です。そのときに使用する

createStatement() メソッドは、下記のシグニチャのものを使用します。

Statement createStatement(int resuktSetType, int resultSetConcurrency)

21

引数の詳細は下記の通りです。

最初にお伝えした引数なしの createStatement() メソッドを使用すると、通常、

「ResultSet.TYPE_FORWARD_ONLY」「ResultSet.CONCUR_READ_ONLY」を指定した場合と同じ

型の ResultSet オブジェクトが返却されます。これも JDBC ドラバーによって、動作が異なる場合があ

るようですが、SQL Server JDBC Driver の既定は、一般的なモードと同じく、

「ResultSet.TYPE_FORWARD_ONLY」「ResultSet.CONCUR_READ_ONLY」です。

6.2.3 バインド変数を使用した問い合わせ

JDBC で は バ ン ド 変 数 を使 用 し た SQL の発行 が 行 え ま す。 下 記 は、 サ ン プル の テ ー ブル

PRODUCTS_TABLE に対して、標準入力から入力された単価以上の金額の製品一覧を抽出するプログラム

です。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

package com.sample.jdbc;

import java.io.IOException;

import java.sql.DriverManager;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.text.DecimalFormat;

public class Sample3 {

/**

* @param args

*/

public static void main(String[] args) {

int price = inputPrice();

22

18

19

20

21

22

23

24

25

26

27

28

29

30

31

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

62

63

64

65

66

67

68

69

70

71

String url = "jdbc:sqlserver://localhost\\SampleDB:1433";

Connection con = null;

try {

con = DriverManager.getConnection(url, "sample_user", "sample_pass");

System.out.println("接続成功");

PreparedStatement stmt = con.prepareStatement(

"SELECT * FROM PRODUCTS_TABLE WHERE PRICE >= ? ORDER BY ID");

stmt.setInt(1, price);

ResultSet r = stmt.executeQuery();

while( r.next() ){

System.out.print(r.getString("NAME"));

System.out.print("(単価"+

DecimalFormat.getCurrencyInstance().format(

Integer.valueOf(r.getString("PRICE")))+"、");

System.out.println("在庫"+r.getString("STOCK")+"個)");

}

r.close();

con.close();

} catch(SQLException e) {

System.out.println("=========================================");

System.out.println("エラーコード=" + e.getErrorCode());

System.out.println("エラーメッセージ=" + e.getLocalizedMessage());

System.out.println("SQL STATE=" + e.getSQLState());

System.out.println("=========================================");

System.exit(1);

}

}

private static int inputPrice(){

byte[] input_buf = new byte[10];

System.out.print ("金額を入力してください。\n>> ");

while(true) {

try {

System.in.read(input_buf);

String input_str = new String(input_buf).trim();

try{

int price = Integer.valueOf(input_str);

System.out.println("");

return price;

} catch ( NumberFormatException e ) {

System.out.print ("数字を入力してください。\n>> ");

continue;

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

26、27 行目を見てください。26 行目の SQL 文で、単価を指定するためのバンド変数を指定しています。

27 行目で、バンド変数に値を設定しています。setInt() メソッドの一つ目の引数は、バンド変数の

ンデックスで、1から始まる数字を指定します。2 つ目の引数には、バンド変数に設定する値を指定しま

23

す。

このプログラムの実行結果は次の通りになります。

6.3 データの更新方法

データの更新には、「6.1 SQL の実行方法」で触れたとおり、executeUpdate() メソッドを使用します。

新規にレコードを 1 つ挿入し、その後、全件抽出したレコードを標準出力に表示するサンプルコードを下記

に挙げます。

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

26

27

28

29

30

31

32

33

package com.sample.jdbc;

import java.sql.DriverManager;

import java.sql.Connection;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import java.text.DecimalFormat;

public class Sample4 {

/**

* @param args

*/

public static void main(String[] args) {

String url = "jdbc:sqlserver://localhost\\SampleDB:1433";

Connection con = null;

try {

con = DriverManager.getConnection(url, "sample_user", "sample_pass");

System.out.println("接続成功");

Statement stmt = con.createStatement();

stmt.executeUpdate(

"INSERT INTO PRODUCTS_TABLE (NAME,PRICE,STOCK) values ('生キャラメル',

500,3000)");

System.out.println("挿入成功");

ResultSet r = stmt.executeQuery("SELECT * FROM PRODUCTS_TABLE ORDER BY ID");

while( r.next() ){

System.out.print(r.getString("NAME"));

System.out.print("(単価"+

DecimalFormat.getCurrencyInstance().format(

24

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

Integer.valueOf(r.getString("PRICE")))+"、");

System.out.println("在庫"+r.getString("STOCK")+"個)");

}

r.close();

con.close();

} catch(SQLException e) {

System.out.println("=========================================");

System.out.println("エラーコード=" + e.getErrorCode());

System.out.println("エラーメッセージ=" + e.getLocalizedMessage());

System.out.println("SQL STATE=" + e.getSQLState());

System.out.println("=========================================");

System.exit(1);

}

}

}

このサンプルの実行結果は下記になります。

上のサンプルでは、23~25 行目で INSERT を実行しています。これは最も簡単な例ですが、

PreparedStatement オブジェクトを使って、動的 SQL として発行することも勿論可能なので、ご自身で

試してみてください。

6.4 トランザクションの制御

前節で使用したサンプルコード (Sample4) では、トランザクション制御が、JDBC ドラバーによって自

動的に行われています。自動でコミットされるタミングは、更新系の SQL が発行される度に、同時に行

われます。これは、先にお伝えした DriverManager.getConnection() メソッドで返却される

Connection オブジェクトが、自動コミットモードという設定で取得されるためです。

このモードはゕプリケーションがトランザクションを意識しないでプログラミングできるというメリットが

あるかもしれませんが、ゕプリケーションによっては、複数の SQL 実行を 1 つのトランザクションで扱い

たいケースはよくある事です。

ここでは、ゕプリケーションでトランザクション制御を行う方法について説明します。

25

6.4.1 自動コミットモードを OFF に設定する。

ゕプリケーションが、自身でトランザクション制御を行うためには、DriverManager.getConnection()

メソッドで Connection オブジェクトを取得する際に、自動コミットモードを指定する引数に OFF (実際

には Boolean で false と指定します) を指定します。あるいは、Connection オブジェクトを取得した後

に、取得した Connection オブジェクトの setAutoCommit() メソッドを呼び出して、自動コミットモ

ードを OFF にします。

自動コミットモードを OFF にした Connection オブジェクトの用意

① Connection オブジェクトを取得する際に設定する方法

Connection con = DriverManager.getConnection(false);

② 取得した Connection オブジェクトに設定する方法

Connection con = DriverManeger.getConnection(); setAutoCommit(false);

6.4.2 トランザクションの開始と完了

JDBC によるトランザクションの開始は、Connection オブジェクトを取得して、最初に更新系の SQL を

発行したタミングか、コミットまたはロールバックを発行した後の、最初に更新系 SQL を発行したタ

ミングになります。

そして、JDBC によるトランザクションの完了、つまり、コミットとロールバックの実行方法は、Connection

オブジェクトに用意されている下記のメソッドを使います。

トランザクション制御のメソッド

① コミット

commit()

② ロールバック

rollback()

サンプルコードの Sample5 を使って、少し実験してみましょう。自動コミットモードを OFF にして、

commit() を呼ばない場合の動作が確認できます。

1

2

3

4

5

package com.sample.jdbc;

import java.sql.DriverManager;

import java.sql.Connection;

import java.sql.ResultSet;

26

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

import java.sql.SQLException;

import java.sql.Statement;

import java.text.DecimalFormat;

public class Sample5 {

/**

* @param args

*/

public static void main(String[] args) {

String url = "jdbc:sqlserver://localhost\\SampleDB:1433";

Connection con = null;

try {

con = DriverManager.getConnection(url, "sample_user", "sample_pass");

con.setAutoCommit(false);

System.out.println("接続成功");

Statement stmt = con.createStatement();

stmt.executeUpdate(

"INSERT INTO PRODUCTS_TABLE (NAME,PRICE,STOCK) values ('生キャラメル',

500,3000)");

stmt.close();

//con.commit();

System.out.println("挿入成功");

stmt = con.createStatement();

ResultSet r = stmt.executeQuery("SELECT * FROM PRODUCTS_TABLE ORDER BY ID");

while( r.next() ){

System.out.print(r.getString("NAME"));

System.out.print("(単価"+

DecimalFormat.getCurrencyInstance().format(

Integer.valueOf(r.getString("PRICE")))+"、");

System.out.println("在庫"+r.getString("STOCK")+"個)");

}

r.close();

con.close();

} catch(SQLException e) {

System.out.println("=========================================");

System.out.println("エラーコード=" + e.getErrorCode());

System.out.println("エラーメッセージ=" + e.getLocalizedMessage());

System.out.println("SQL STATE=" + e.getSQLState());

System.out.println("=========================================");

System.exit(1);

}

}

}

これを実行した結果が下記になりますが、期待通りの動作になっていないようです。最終行に「生キャラメ

ル」が抽出されています。なぜでしょうか。

27

念のため、SQL Server Management Studio で「生キャラメル」が登録されているかを確認してみましょ

う。下図がその結果ですが、「生キャラメル」がこちらには登録されていません。

これは期待通りの動作です。

では、なぜ Java プログラムの方では、「生キャラメル」のレコードが取得できたのでしょうか。

よく考えると当然の事でありますが、更新と検索を同じ接続を使って行っているためです。データベースに

コミットしていませんが、その接続の中でのみデータの更新状態が維持されている訳です。

7 ちょっと高度なプログラミング

ここまでで、JDBC を使った基本的なプログラミング方法について解説してきました。ここでは、もう少し

高度なプログラミング方法について触れたいと思います。

7.1 ResultSet を使った更新処理

データベースから抽出した結果セットに対して、変更などの操作を行う場合は、ResultSet オブジェクトの

28

カーソル操作を使いながら処理する事ができます。その場合、「6.2.2 カーソル操作」で触れたとおり、

Connection オ ブ ジ ェ ク ト の createStatement() メ ソ ッ ド を 呼 び 出 す 際 の 引 数 に 、

ResultSet.CONCUR_UPDATABLE を指定する必要があります。

下記にサンプルを示します。このプログラムは、最初に商品「生キャラメル」のレコードを新規に挿入し、

次に、「生キャラメル」という商品名のレコードに対して、商品名を「チョコレートケーキ」に変更する操作

を行っています。最後に「チョコレートケーキ」という商品名のレコードを削除しています。

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

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

package com.sample.jdbc;

import java.sql.DriverManager;

import java.sql.Connection;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import java.text.DecimalFormat;

public class Sample6 {

/**

* @param args

*/

public static void main(String[] args) {

String url = "jdbc:sqlserver://localhost\\SampleDB:1433";

Connection con = null;

try {

con = DriverManager.getConnection(url, "sample_user", "sample_pass");

System.out.println("接続成功");

Statement stmt = con.createStatement(

ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

String SQL = "SELECT * FROM PRODUCTS_TABLE ORDER BY ID";

ResultSet r = stmt.executeQuery(SQL);

System.out.println("初期のテーブルの状態.......................................");

printRows(r);

/*

* 生キャラメルのレコードを挿入

*/

r.moveToInsertRow();

r.updateString("NAME", "生キャラメル");

r.updateInt("PRICE", 500);

r.updateInt("STOCK", 3000);

r.insertRow();

System.out.println(

"INSERT実行後のテーブルの状態.................................");

SQL = "SELECT * FROM PRODUCTS_TABLE ORDER BY ID";

r = stmt.executeQuery(SQL);

printRows(r);

/*

* 生キャラメルのレコードの商品名を「チョコレートケーキ」に変更

*/

SQL = "SELECT * FROM PRODUCTS_TABLE";

r = stmt.executeQuery(SQL);

while( r.next() ) {

29

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

if ( "生キャラメル".equals(r.getString("NAME")) ) {

r.updateString("NAME", "チョコレートケーキ");

r.updateRow();

}

}

System.out.println(

"UPDATE実行後のテーブルの状態.................................");

SQL = "SELECT * FROM PRODUCTS_TABLE ORDER BY ID";

r = stmt.executeQuery(SQL);

printRows(r);

/*

* チョコレートケーキのレコードを削除

*/

SQL = "SELECT * FROM PRODUCTS_TABLE WHERE NAME='チョコレートケーキ'";

r = stmt.executeQuery(SQL);

r.first();

r.deleteRow();

System.out.println(

"DELETE実行後のテーブルの状態.................................");

SQL = "SELECT * FROM PRODUCTS_TABLE ORDER BY ID";

r = stmt.executeQuery(SQL);

printRows(r);

stmt.close();

r.close();

con.close();

} catch(SQLException e) {

System.out.println("=========================================");

System.out.println("エラーコード=" + e.getErrorCode());

System.out.println("エラーメッセージ=" + e.getLocalizedMessage());

System.out.println("SQL STATE=" + e.getSQLState());

System.out.println("=========================================");

System.exit(1);

}

}

private static void printRows( ResultSet r ) throws SQLException {

r.first();

do {

System.out.print(r.getString("NAME"));

System.out.print("(単価"+

DecimalFormat.getCurrencyInstance().format(

Integer.valueOf(r.getString("PRICE")))+"、");

System.out.println("在庫"+r.getString("STOCK")+"個)");

} while( r.next() );

System.out.println();

}

}

30

このプログラムを実行した結果は下記の通りとなります。

挿入時は、moveToInsertRow() で挿入ポントに移動してから、そこで値を設定し、最後に insertRow() で

レコードを挿入します。

更新時は、更新対象のレコードへカーソルを移動し、そこで値を変更してから、最後に updateRow()

メソッドで更新を行います。

削除も同様に、削除対象のレコードへカーソルを移動し、deleteRow() メソッドで削除を行います。

7.2 DataSource オブジェクトを使った接続

J2EE 環境で JDBC 接続を行う際に推奨される機構としてデータソースがあります。サーバー サドのゕプ

リケーションを開発する場合は必須の知識になります。データソースは、通常の接続のほか、接続プールを

利用する事が可能です。不特定多数の利用者を想定したゕプリケーションなどでは、大量にデータベースへ

の接続が発生し得ます。その際に、データベース サーバーに必要以上の負荷を与えないために、接続プール

は極めて有効な手段となります。

接続プールの仕組み自体は、データベース接続を語るうえで一般的な話であるため、ここでは説明を割愛さ

せて頂き、Java でデータソースを利用する際のプログラミング方法についてのみ触れます。下記にサンプル

31

を挙げます。

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

26

27

28

29

30

31

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

package com.sample.jdbc.servlet;

import java.io.IOException;

import java.sql.Connection;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import java.text.DecimalFormat;

import java.util.ArrayList;

import javax.naming.InitialContext;

import javax.naming.NamingException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.sql.DataSource;

public class Sample7 extends HttpServlet {

/**

*

*/

private static final long serialVersionUID = 1L;

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {

ArrayList<String> rows = new ArrayList<String>();

Connection con = null;

try {

InitialContext ic = null;

DataSource ds = null;

try {

ic = new InitialContext();

ds = (DataSource)ic.lookup("java:comp/env/jdbc/SampleDB");

} catch (NamingException e) {

e.printStackTrace();

rows.add("データソースの検索に失敗しました。");

req.setAttribute("RESULT", rows);

req.getRequestDispatcher("result.jsp").forward(req, resp);

return;

}

con = ds.getConnection();

Statement stmt = con.createStatement();

ResultSet r = stmt.executeQuery("SELECT * FROM PRODUCTS_TABLE ORDER BY ID");

while( r.next() ){

rows.add(r.getString("NAME"));

rows.add("(単価"+

DecimalFormat.getCurrencyInstance().format(Integer.valueOf(r.getString("PRICE")))+"、");

rows.add("在庫"+r.getString("STOCK")+"個)<br/>");

}

r.close();

con.close();

32

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

req.setAttribute("RESULT", rows);

req.getRequestDispatcher("result.jsp").forward(req, resp);

} catch(SQLException e) {

rows.add("=========================================<br/>");

rows.add("エラーコード=" + e.getErrorCode()+”<br/>”);

rows.add ("エラーメッセージ=" + e.getLocalizedMessage()+”<br/>”);

rows.add ("SQL STATE=" + e.getSQLState()+”<br/>”);

rows.add ("=========================================<br/>");

rows.add("データソースの検索に失敗しました。<br/>”);

req.setAttribute("RESULT", rows);

req.getRequestDispatcher("result.jsp").forward(req, resp);

}

}

}

このサンプルを実行するにあたり、私は Apache Tomcat 5.5 を使いましたが、そちらの設定は下記の通り

になります。J2EE に由来する設定の説明は割愛します。

server.xml

コンテキストの設定に、データソースの定義も、ここで併せて行います。30 行目から 40 行目で指定して

います。

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

26

27

28

29

30

31

32

33

<?xml version="1.0" encoding="UTF-8"?> <Server port="8005" shutdown="SHUTDOWN">

<Listener className="org.apache.catalina.core.AprLifecycleListener"/> <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener"/> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/> <Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/> <GlobalNamingResources>

<Environment name="simpleValue" type="java.lang.Integer" value="30"/> <Resource auth="Container"

description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase"

pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/> </GlobalNamingResources>

<Service name="Catalina"> <Connector acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" enableLookups="false" maxHttpHeaderSize="8192" maxSpareThreads="75" maxThreads="150" minSpareThreads="25" port="8080" redirectPort="8443"/>

<Connector enableLookups="false" port="8009" protocol="AJP/1.3" redirectPort="8443"/>

<Engine defaultHost="localhost" name="Catalina"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm"

resourceName="UserDatabase"/>

<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true" xmlNamespaceAware="false" xmlValidation="false">

<Context docBase="SampleJ2EEWeb" path="/sample" reloadable="true" source="org.eclipse.jst.j2ee.server:SampleJ2EEWeb">

<Resource

auth="Container"

33

34

35

36

37

38

39

40

41

42

43

44

45

driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver" name="jdbc/SampleDB" username="sample_user" password="sample_pass" type="javax.sql.DataSource" url="jdbc:sqlserver://localhost\\SampleDB:1433"/>

</Context>

</Host>

</Engine>

</Service>

</Server>

web.xml

server.xml で設定したデータソースを参照するため、27~31 行目の設定を行っています。

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

26

27

28

29

30

31

32

<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns=http://java.sun.com/xml/ns/j2ee

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>SampleJ2EEWeb</display-name>

<servlet>

<description>

</description>

<display-name>Sample7</display-name>

<servlet-name>Sample7</servlet-name>

<servlet-class>

com.sample.jdbc.servlet.Sample7</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>Sample7</servlet-name>

<url-pattern>/Sample7</url-pattern>

</servlet-mapping>

<welcome-file-list>

<welcome-file>index.html</welcome-file>

<welcome-file>index.htm</welcome-file>

<welcome-file>index.jsp</welcome-file>

<welcome-file>default.html</welcome-file>

<welcome-file>default.htm</welcome-file>

<welcome-file>default.jsp</welcome-file>

</welcome-file-list>

<resource-ref>

<res-ref-name>jdbc/SampleDB</res-ref-name>

<res-type>javax.sql.DataSource</res-type>

<res-auth>Container</res-auth>

</resource-ref>

</web-app>

以上の設定を行って、ブラウザで「http://localhost:8080/sample/Sample7」にゕクセスすると、下記の

通り表示されます。

34

35

7.3 JDBC ドライバーのログを活用する

JDBC プログラミングにおけるデバッグでは、通常、発行した SQL をゕプリケーション自身でログに出力

するか、デバッガを使用するなどの方法がありますが、JDBC ドラバーのログを見てみるという方法もあ

ります。出力された内容を見てもほとんどは分かりませんが、JDBC ドラバーが受け付けた SQL 文など

のログも出力されるので、とにかくトラブル解決の手掛かりが欲しいときなど、役に立つ場合があるかもし

れませんので、知っておくと便利だと思います。SQL Server JDBC Driver では、java.util.logging パ

ッケージを利用したログ出力をサポートしています。

例えば下記のように logging.properties を設定します。

1

2

3

4

5

handlers = java.util.logging.ConsoleHandler

.level = ALL

com.microsoft.sqlserver.jdbc.Logging.level=OFF

java.util.logging.ConsoleHandler.level = ALL

java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

以上の設定で次のような出力結果が得られます。

8 おわりに

以上で本書の JDBC に関する解説は終了しました。JDBC は、データベース サーバーが様々に存在するた

め、それぞれに専用の JDBC ドラバーが存在すると説明しましたが、それ故に、JDBC ドラバーの実装

範囲や挙動に違いが見られる場合があります。1 つ例を挙げると、SQL Server JDBC Driver では、JDBC

API で 定 義 し て い る カ ー ソ ル の 種 類 の ほ か 、 独 自 の 設 定 方 法 が 提 供 さ れ て い る よ う で す 。

(http://msdn.microsoft.com/ja-jp/library/ms378405.aspx)

これは SQL Server を最適に利用するために提供されているものですので、ゕプリケーションシステムの要

36

件によっては、それらの機能を有効に活用すべきだと思います。そのためにも JDBC ドラバーのマニュゕ

ルには是非目を通されることをお勧めします。

また、今回本書では、ラージオブジェクトの操作やストゕドプロシージャの呼び出しには触れられませんで

したが、本書で説明した内容を理解されていれば、SUN Microsystems Inc.の JDK のマニュゕルや、JDBC

ドラバーのドキュメントを参照されるだけで、簡単にコーデゖングできることがお分かりになると思いま

す。最後に、それらのドキュメントへのリンクを載せておきます。

9 参考文献

JDKTM 6 ドキュメント-JDBC(SUN Microsystems Inc.)

http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/jdbc/index.html

JavaTM Platform, Standard Edition 6 API 仕様(SUN Microsystems Inc.)

http://java.sun.com/javase/ja/6/docs/ja/api/

SQL Server JDBC Driver 2.0 Documentation(Microsoft Corporation.)

http://msdn.microsoft.com/ja-jp/library/dd903047%28SQL.10%29.aspx