S-JIS[2007-05-01/2021-02-10] 変更履歴

JDBC

JDBCは、Javaでデータベース(RDB)にアクセスする為のAPI。
テーブルやビュー、ストアドプロシージャ等にアクセスできる。

JDBCとは商標(つまり固有名詞扱い)なのであって、何かの略というわけではないとのこと。
「Java Database Connectivity」の略だというのが一番広まっているらしいけど、まぁどう考えてもODBC(Open DataBase Connectivity)のJava版、という感じだし。


JDBCを使ったSQLの実行方法

JDBCのドライバーと共にjava.sql.*やjavax.sql.*のクラスを使うことにより、DBにアクセスする。

標準的なクラスの使い方はJDBCで決められている。

実際に動かす(DBに接続する)にはJDBCドライバーが必要。
ドライバーはDBMSのベンダーAPサーバー(例えばWeblogicとか)のベンダーが提供しているので、実行環境に応じたドライバーを使えばよい。

DriverManagerの初期化の方法は、JDBC(JDK)のバージョンによって異なる。[2007-06-28]

JDBC JDK 備考
JDBC3.0 JDK1.4からサポート Class.forName("使用するドライバーのクラス名");
ドライバークラス静的初期化子の中でDriverManagerに自分を登録している。
JDBC4.0 JDK1.6からサポート Class.forName()を呼ばなくてもよくなった。(呼んでも大丈夫)
JDBCのjarファイルの中でクラス名が指定されるようになった為。

DriverManagerの仕組み(Class.forName()の意味) [2009-04-13]

データソースを使う場合はAPサーバーが初期化してくれるので、特に気にする必要は無い。[2008-08-16]
(データソースの使用とは: APサーバーにDB接続情報を定義しておき、JNDI経由でそれを取得する方法)
JBossでデータソースを使ってOracleにアクセスする例


タイプ

JDBCドライバーには、TYPE1〜4という4つの型(カテゴリー)がある。

Type1 JDBC-ODBCブリッジ JDBC呼び出しをODBCに渡して(ODBCを経由して)DBにアクセスする。
したがってODBCが必須。
Type2 Native-API JDBC呼び出しを“DBMSの専用ライブラリー(OS依存)”に渡してDBにアクセスする。
したがってライブラリーが必須。
Type3 ネットワークプロトコル JDBC呼び出しを“DBMSに依存しないネットプロトコル”で(APサーバーを介して)DBにアクセスする。
Type4 ネイティブプロトコル JDBC呼び出しを“DBMSが使用するネットプロトコル”に変換してDBに直接アクセスする。
Javaのみで作られているので移植性は高い。基本的にTCP/IPを使用する。

Oracleの場合、Thin(シン)ドライバーと呼ばれるものはType4ociドライバー(Oracle Call Interface)と呼ばれるものはType2(Oracleクライアントをインストールする必要があるがOracleの全機能を使える)。

なお、ociドライバーを使う場合はOracleクライアントのtnsnames.oraの設定が使用される(SQL*Plusでのログインと一緒)。[2008-10-25]
また、環境変数ORACLE_HOMEが指定されている場合は、それにも依存する。(たぶんtnsnames.oraを探すのに使われる)


JDBCドライバーのバージョン確認方法

JDBCドライバーのバージョンを確認するには、DatabaseMetaDataクラスを使用する。[2008-10-19]
しかしこれはConnectionから取得するものらしく、実際にDBに接続しないと使えない。
(connectしないとDriverManagerのバージョンが分からないのは不思議な気もするが、connectしないとDriverインスタンスが決定できないから仕方ないのか)

以下、OracleのOracleDriverのバージョンを表示する例。

	public static void main(String[] args) throws Exception {

		//JDBCドライバー(ojdbc14.jarとか)をクラスパスに入れておく必要あり
		Class.forName("oracle.jdbc.driver.OracleDriver");
		Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ora92", "scott", "tiger");

		DatabaseMetaData meta = conn.getMetaData();
		System.out.println(meta.getDriverName() + " " + meta.getDriverVersion());
		System.out.println(driver.getMajorVersion());
		System.out.println(driver.getMinorVersion());

		conn.close();
	}
Oracle JDBC driver 9.2.0.1.0
9
2

ちなみに、OracleのJDBCドライバーのjarファイル(ojdbc14.jarとか)のMANIFEST.MFにバージョンっぽい数字が入っているが、これと上記のバージョンは異なる模様。


ドライバーから直接バージョンを取得することもできるが、取れる値はメタデータのものとは異なるようだ…。[2009-04-14]

		@SuppressWarnings("unchecked")
		Class<Driver> c = (Class<Driver>) Class.forName("oracle.jdbc.driver.OracleDriver");
		Driver driver = c.newInstance();

		System.out.println(driver);
		System.out.println(driver.getMajorVersion());
		System.out.println(driver.getMinorVersion());
oracle.jdbc.driver.OracleDriver@141d683
1
0

また、OracleのJDBCドライバーのjarファイル(ojdbc5.jarとか)は、以下のように実行することでバージョンが表示される。[2008-12-15]

C:\app\hishidama\product\11.1.0\client_1\jdbc\lib>java -jar ojdbc5.jar
Oracle 11.1.0.6.0-Production JDBC 3.0 compiled with JDK5

C:\app\hishidama\product\11.1.0\client_1\jdbc\lib>java -jar ojdbc6_g.jar
Oracle 11.1.0.6.0-Production JDBC 4.0 debug compiled with JDK6

タイムアウト時間の設定

Statement#setQueryTimeout(秒)、あるいはRowSet#setQueryTimeout(秒)でDBアクセスのタイムアウト時間を設定できる。[2009-01-19]
タイムアウトすると例外が発生する。
(ただし、指定した時間きっかりでタイムアウトが発生するとは限らない。クライアント側のCPUが遅い(負荷が高い)せいかと思うのだが、多少ずれ込む…そんなの当たり前?


Oracleの場合、setQueryTimeout()でタイムアウトすると、ORA-01013「ユーザーによって現行の操作の取消しが要求されました。」の例外が発生する。
もし実行しているSQLが「SELECT 〜 FOR UPDATE WAIT 時間」によってタイムアウトした場合、その例外(ORA-30006)の方が優先される。

SELECT 〜 FOR UPDATE WAIT」による無限待ちの場合、setQueryTimeout()によるタイムアウトはかなり長いこと発生しない。
(1秒や5秒を指定していても5分弱くらい待つ)
ロック待ちが解除されたときにタイムアウト時間を経過しているとORA-01013の例外が発生する。


参考:


Java目次へ戻る / 新機能へ戻る / 技術メモへ戻る
メールの送信先:ひしだま