7 サーバー側内部ドライバ
この章の構成は、次のとおりです。
7.1 サーバー側内部ドライバの概要
サーバー側内部ドライバは、Oracle DatabaseとOracle Java仮想マシン(Oracle JVM)とも呼ばれる埋込みJava仮想マシンに結び付けられています。このドライバは、データベースと同じプロセスの一部として動作します。また、デフォルトのセッション(Oracle JVMが起動されたセッションと同じセッション)内で動作します。各Oracle JVMセッションには、存在するデータベース・セッションに対して1つの暗黙的なネイティブ接続があります。この接続は概念的で、Javaオブジェクトではありません。これはこのセッションに固有な側面であり、JVM内でオープンまたはクローズできません。
サーバー側内部ドライバはデータベース・サーバー内で動作するよう最適化されており、このドライバを使用するとローカル・データベース上のSQLデータおよびPL/SQLサブプログラムに直接アクセスできます。JVM全体は、データベースおよびSQLエンジンと同じアドレス空間内で動作します。SQLエンジンへのアクセスはファンクション・コールです。これによって、Java Database Connectivity(JDBC)アプリケーションのパフォーマンスが向上し、SQLエンジンへのアクセスにリモートOracle Netコールを実行するよりも速くなります。
サーバー側内部ドライバは、クライアント側ドライバと同じ機能、Application Program Interface(API)およびOracle拡張機能をサポートします。これにより、アプリケーションのパーティション化が非常に簡単になります。たとえば、データ集中処理型のJavaアプリケーションがある場合は、アプリケーション固有のコールを修正しなくても、パフォーマンスを向上させるために簡単にデータベース・サーバーに移動できます。
7.2 データベースへの接続
前の項で説明したように、サーバー側内部ドライバはデフォルトのセッション内で動作します。したがって、すでに接続された状態になっています。デフォルト接続にアクセスするには、次の2つのメソッドを使用できます。
-
次のいずれかの形式をURL文字列として、
OracleDataSource.getConnection
メソッドを使用します。-
jdbc:oracle:kprb
-
jdbc:default:connection
-
jdbc:oracle:kprb:
-
jdbc:default:connection:
-
-
OracleDriver
クラスのOracle固有のdefaultConnection
メソッドを使用します。
通常はdefaultConnection
の使用をお薦めします。
ノート:
サーバー側内部ドライバと接続するためにOracleDriver
クラスを登録する必要はなくなりました。
OracleDriverクラスのdefaultConnectionメソッドによる接続
oracle.jdbc.OracleDriver
クラスのdefaultConnection
メソッドは、Oracle拡張機能で、常に同じ接続オブジェクトを戻します。発生した接続オブジェクトを別の変数名に割り当て、このメソッドを複数回コールしたとしても、1つの接続オブジェクトのみが再利用されます。
defaultConnection
コールに接続文字列を含める必要はありません。次に例を示します。
import java.sql.*; import oracle.jdbc.*; class JDBCConnection { public static Connection connect() throws SQLException { Connection conn = null; try { // connect with the server-side internal driver
conn = ora.defaultConnection(); } } catch (SQLException e) {...} return conn; } }
この例にはconn.close
コールがないことに注意してください。JDBCコードがターゲット・サーバー内で実行されている場合、接続は暗黙的なデータ・チャネルで、クライアントからの場合のように明示的な接続インスタンスではありません。クローズしないでください。
OracleDriverは、デフォルトの接続インスタンスを格納するための静的な値です。接続が存在しクローズされていない場合に、メソッドOracleDriver.defaultConnection
はこのデフォルトの接続インスタンスを戻します。それ以外の場合、新しいオープン・インスタンスを作成し、静的な値に格納してコール元に戻します。
通常、OracleDriver.defaultConnection
メソッドを使用します。このメソッドは、高速でリソースをあまり使用しません。Javaストアド・プロシージャは注意深く記述する必要があります。たとえば、各コールを終了する前に文をクローズします。
通常、デフォルトの接続インスタンスはクローズしないでください。このインスタンスは複数の場所に格納される可能性がある単一インスタンスであり、クローズするとそれぞれの場所が使用できなくなります。クローズすると、それ以降にOracleDriver.defaultConnection
メソッドをコールしたときに、新しいオープン・インスタンスが作成されます。
OracleDataSource.getConnectionメソッドによる接続
ターゲット・サーバー内で実行中のコードから内部サーバー接続に接続するには、次のいずれかのURLとともに、OracleDataSource.getConnection
メソッドを使用できます。
OracleDataSource ods = new OracleDataSource(); ods.setURL("jdbc:oracle:kprb"); Connection conn = ods.getConnection();
または
OracleDataSource ods = new OracleDataSource(); ods.setURL("jdbc:default:connection"); Connection conn = ods.getConnection();
URL内で指定したユーザー名またはパスワードは、デフォルトのサーバー接続への接続では無視されます。
OracleDataSource.getConnection
メソッドをコールするたびに、このメソッドは新しいJava Connection
オブジェクトを戻します。オブジェクト・マップまたは型マップを操作している場合は、OracleDataSource.getConnection
をコールするたびに、このメソッドが新しい接続オブジェクトを戻すということに重要な意味があります。型マップは、特定のConnection
オブジェクトおよびそのオブジェクトの一部である状態に関連付けられます。プログラムの一部として複数の型マップを使用する場合は、getConnection
をコールして、各型マップに対して新しいConnection
オブジェクトを作成できます。
ノート:
OracleDataSource.getConnection
メソッドはコールするたびに新規オブジェクトを戻しますが、毎回、新しいデータベース接続を作成するわけではありません。同じ暗黙的なネイティブ接続を使用し、同じセッション状態(特にローカル・トランザクション)を共有します。
7.3 セッション・コンテキストおよびトランザクション・コンテキストについて
サーバー側ドライバは、デフォルト・セッションおよびデフォルト・トランザクションのコンテキストで動作します。デフォルト・セッションとは、JVMが起動されたセッションです。サーバー上では、事実上データベースにすでに接続されています。これは、デフォルト・セッションがないクライアント側とは異なります。クライアント側では、明示的にデータベースに接続する必要があります。
サーバーでは、自動コミット・モードは無効になっています。接続オブジェクトで適切なメソッドを使用して、明示的にトランザクションのCOMMIT
およびROLLBACK
操作を管理する必要があります。
conn.commit();
または
conn.rollback();
ノート:
ベスト・プラクティスとして、サーバー内ではトランザクションをコミットまたはロールバックしないことをお薦めします。
7.4 サーバー上でのJDBCのテスト
クライアント上で実行できるJDBCプログラムはほとんどすべてサーバー上でも実行できます。samples
ディレクトリ内のすべてのプログラムは、少し修正するのみでサーバー上で実行できます。通常、修正は接続文に関するもののみです。
データベースへの接続を取得するための次のようなコード・フラグメントについて考えてみます。
ods.setUrl( "jdbc:oracle:oci:@(DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=cluster_alias) (PORT=5221)) (CONNECT_DATA=(SERVICE_NAME=orcl)))"); ods.setUser("HR"); ods.setPassword("hr"); Connection conn = ods.getConnection();
サーバー側内部ドライバで使用できるように、このコード・フラグメントを変更できます。サーバー側内部ドライバでは、ユーザー、パスワードまたはデータベースの情報は不要です。接続文は次のように記述します。
ods.setUrl( "jdbc:oracle:kprb:@"); Connection conn = ods.getConnection();
ただし、接続を取得するには、次のようにOracleDriver.defaultConnection
メソッドをコールするのが最も便利な方法です。
Connection conn = OracleDriver.defaultConnection();
7.5 サーバーへのアプリケーションのロード
サーバーにアプリケーションをロードする場合は、クライアントでコンパイル済の.class
ファイルをロードするか、.java
ソース・ファイルをロードして、サーバーで自動的にコンパイルできます。
7.5.1 loadjavaユーティリティの使用
loadjava
ユーティリティを使用してファイルをロードします。コマンドラインでソース・ファイル名を指定するか、Javaアーカイブ(JAR)ファイルにそのファイルを格納して、コマンドラインでそのJARファイル名を指定します。
実際のユーティリティを実行するloadjava
スクリプトは、Oracleホームのbin
ディレクトリにあります。このディレクトリは、Oracleをインストールすると自動的に作成されます。
ノート:
loadjava
ユーティリティは圧縮ファイルをサポートしています。
サーバーへのクラス・ファイルのロード
アプリケーションに3つのクラス・ファイルFoo1.class
、Foo2.class
およびFoo3.class
がある場合を考えてみます。各クラスは、サーバーで独自のクラス・スキーマ・オブジェクトに書き込まれます。
次のように、JDBC Oracle Call Interface(OCI)のデフォルト・ドライバを使用して、クラス・ファイルをロードできます。
-
クラス・ファイル名を個別に指定します。
loadjava -user HR Foo1.class Foo2.class Foo3.class Password: password
-
ワイルドカードを使用してクラス・ファイル名を指定します。
loadjava -user HR Foo*.class Password: password
-
クラス・ファイルが格納されているJARファイルを指定します。
loadjava -user HR Foo.jar Password: password
次のように、JDBC Thinドライバを使用してファイルをロードできます。
loadjava -thin -user HR@localhost:5221:orcl Foo.jar
Password: password
ノート:
Oracle Database 12cリリース1 (12.1)以降、JDK 6およびJDK 7がサポートされています。ただし、ある時点でアクティブなJVMは1つのみです。
クラスは、サーバーのアクティブなランタイム・バージョンよりも新しいバージョンのJDKを使用してコンパイルされないようにしてください。
サーバーへのソース・ファイルのロード
.java
ソース・ファイルをロードする際にloadjava -resolve
オプションを有効にすると、サーバー側コンパイラはロード時にアプリケーションをコンパイルします。その結果、オリジナル・ソース・コードのソース・スキーマ・オブジェクトとコンパイル済出力の1つ以上のクラス・スキーマ・オブジェクトの両方が生成されます。
-resolve
を指定しない場合は、ソースはコンパイルされずに、ソース・スキーマ・オブジェクトにロードされます。ただし、この場合は、ソースで定義されたクラスを最初に使用しようとしたときに、ソースが暗黙的にコンパイルされます。
たとえば、デフォルトのJDBC OCIドライバを使用して、Foo.java
をロードしてコンパイルするには、次のようにloadjava
を実行します。
loadjava -user HR -resolve Foo.java
Password: password
あるいは、次のコマンドを入力し、JDBC Thinドライバを使用してロードします。
loadjava -thin -user HR@localhost:5221:orcl -resolve Foo.java
Password: password
いずれの方法でも、ソース・スキーマ・オブジェクトに加えて、適切なクラス・スキーマ・オブジェクトが作成されます。
ノート:
通常はできるかぎりクライアントでソースをコンパイルし、ソース・ファイルではなく、.class
ファイルをサーバーにロードすることをお薦めします。
7.5.2 JVMコマンドラインの使用
JVMコマンドライン・オプションを使用してファイルをロードすることもできます。Oracle JVMへのコマンドライン・インタフェースは、JDKまたはJREのシェル・コマンドの使用方法と似ています。次のことが可能です。
-
標準の
-classpath
構文を使用して、ロードするクラスの検索場所を示します。 -
標準の
-D
構文を使用して、システム・プロパティを設定します。
このインタフェースは、文字列(VARCHAR2
)引数を取り、この引数をコマンドライン入力として解析するPL/SQLファンクションです。形式が適切であれば、Oracle JVMで指定のJavaメソッドを実行します。これを実行するために、PL/SQLのパッケージDBMS_JAVA
には次のファンクションが用意されています。
-
runjava
runjava
ファンクションを使用するには、次のようにします。FUNCTION runjava(cmdline VARCHAR2) RETURN VARCHAR2;
-
runjava_in_current_session
runjava_in_current_session
ファンクションを使用するには、次のようにします。FUNCTION runjava_in_current_session(cmdline VARCHAR2) RETURN VARCHAR2;
ノート:
Oracle Database 11gリリース1以降には、Oracle JVM環境用のJust-In-Time(JIT)コンパイラがあります。Oracle JVMのJITコンパイラでは、以前のネイティブ・コンパイラと比較して高度な技術を使用し、動的に生成されたコードをコンパイルするため、実行速度が上がります。以前のネイティブ・コンパイラと異なり、JITコンパイラにはCコンパイラが必要ありません。プラグインのサポートがなくても有効です。