この章では、Java Database Connectivity(JDBC)データソースを使用したアプリケーションのデータベースへの接続と、データベースを記述するURLについて説明します。この章では、次の項目について説明します。
データソースは、使用するデータベースまたはその他のリソースを指定するための標準汎用オブジェクトです。データソースの概念は、JDBC 2.0 Extension Application Program Interface(API)で導入されました。データソースは、便宜性と移植性のために、Java Naming and Directory Interface(JNDI)エントリにバインドできるため、データベースには論理名でアクセスできます。
データソース機能は、以前のJDBC DriverManager
機能の完全な代替機能を提供します。いずれの機能も同じアプリケーションで使用できますが、使用しているアプリケーションはデータソースに移行することをお薦めします。
この項には、次の項目が含まれます。
JNDI標準は、リモート・サービスおよびリソースを検出してアクセスする方法をアプリケーションに提供します。これらのサービスは、エンタープライズ・サービスにも可能です。ただし、JDBCアプリケーションの場合は、これらのサービスにデータベース接続およびサービスが含まれます。
JNDIを使用すると、アプリケーションはアプリケーション・コードからベンダー固有の構文を削除し、論理名を使用してこれらのサービスにアクセスできます。JNDIには、目的のサービスの特定のソースと論理名を関連付ける機能があります。
すべてのOracle JDBCデータソースでは、JNDIを参照できます。開発者が必ずしもこの機能を使用する必要はありませんが、JNDI論理名を使用してデータベースにアクセスすると、コードの移植性が高まります。
注意: JNDIの機能を使用するには、ファイルjndi.jar がCLASSPATH 環境変数にある必要があります。このファイルは、インストールCDのJava製品に入っています。このファイルは個別にCLASSPATH 環境変数に追加する必要があります。Sun社のWebサイトから取得することもできますが、オラクル社が提供するバージョンを使用することをお薦めします。このバージョンは、Oracleドライバでのテストを済ませています。 |
JNDIを使用するデータソース機能では、ベンダー固有のJDBCドライバ・クラス名を登録する必要はなく、URLとその他のプロパティの論理名を使用できます。このため、データベース接続をオープンするためのコードは、他の環境に移植できます。
JDBCデータソースは、標準javax.sql.DataSource
インタフェースを実装するクラスのインスタンスです。
public interface DataSource { Connection getConnection() throws SQLException; Connection getConnection(String username, String password) throws SQLException; ... }
Oracleでは、このインタフェースをoracle.jdbc.pool
パッケージのOracleDataSource
クラスに実装しています。オーバーロードされたgetConnection
メソッドは、データベースへの接続を戻します。
他の値を使用するには、適切なsetterメソッドを使用してプロパティを設定します。代替のユーザー名とパスワードを設定するには、入力としてこれらの値を取るgetConnection
メソッドを使用することもできます。この設定は、プロパティ設定よりも優先されます。
注意: OracleDataSource クラスとすべてのサブクラスは、java.io.Serializable インタフェースとjavax.naming.Referenceable インタフェースを実装します。 |
DataSource
インタフェースを実装するすべてのクラスと同様に、OracleDataSource
クラスは、接続するデータベースの指定に使用できる一連のプロパティを提供します。これらのプロパティはJavaBeansのデザインパターンに従います。
表8-1および表8-2に、OracleDataSource
プロパティを示します。表8-1のプロパティは、Sun社の仕様に従った標準プロパティです。表8-2のプロパティはOracle拡張機能です。
注意: Oracleは標準roleName プロパティを実装していません。 |
表8-1 標準データソース・プロパティ
名前 | 型 | 説明 |
---|---|---|
|
|
サーバー上の特定のデータベース名。Oracleの用語ではSIDとも呼ばれます。 |
|
|
基礎となるデータソース・クラスの名前。接続プーリングの場合、これはプーリングされた基礎となる接続データソース・クラスです。分散トランザクションの場合、これは基礎となるXAデータソース・クラスです。 |
|
|
データソースの説明。 |
|
|
サーバーと通信するためのネットワーク・プロトコル。Oracleの場合、これはJDBC Oracle Call Interface(OCI)ドライバのみに適用され、デフォルトは |
|
|
接続するユーザーのパスワード。 |
|
|
サーバーが要求をリスニングするポート番号。 |
|
|
データベース・サーバーの名前。 |
|
|
ログイン用の名前。 |
OracleDataSource
クラスは、標準プロパティである次のsetメソッドとgetメソッドを実装します。
public synchronized void setDatabaseName(String dbname)
public synchronized String getDatabaseName()
public synchronized void setDataSourceName(String dsname)
public synchronized String getDataSourceName()
public synchronized void setDescription(String desc)
public synchronized String getDescription()
public synchronized void setNetworkProtocol(String np)
public synchronized String getNetworkProtocol()
public synchronized void setPassword(String pwd)
public synchronized void setPortNumber(int pn)
public synchronized int getPortNumber()
public synchronized void setServerName(String sn)
public synchronized String getServerName()
public synchronized void setUser(String user)
public synchronized String getUser()
表8-2 Oracle拡張データソース・プロパティ
名前 | 型 | 説明 |
---|---|---|
|
|
キャッシュの名前を指定します。キャッシュを作成した後は変更できません。 |
|
|
暗黙的接続キャッシュのプロパティを指定します。 |
|
|
暗黙的接続キャッシュが使用中かどうかを指定します。 |
|
|
接続プロパティを指定します。 |
|
Oracle JDBCドライバのタイプを指定します。 |
|
|
|
高速接続フェイルオーバーが使用中かどうかを指定します。 |
|
|
暗黙的文接続キャッシュが有効かどうかを指定します。 |
|
|
このデータソースがデータベースへの接続の試行中に待機する最大時間(秒)を指定します。 |
|
|
このデータソースのログ・ライターを指定します。 |
|
|
アプリケーションのキャッシュ内に存在する文の最大数を指定します。 |
|
|
このデータソースに対するデータベース・サービス名を指定します。 |
|
TNSエントリ名を指定します。OCIドライバのみに関係します。TNSエントリ名は、 OCIドライバでネイティブXA機能を使用する場合は、この |
|
|
データベース接続文字列のURLを指定します。以前のバージョンのOracle Databaseから移行する際の便宜を考えて提供されるものです。Oracle |
|
|
OCIドライバでネイティブXA機能を使用する場合は、 この |
|
|
|
FaN/ONSイベントのリモートでのサブスクライブに使用するONS構成を指定します。 |
注意:
|
OracleDataSource
クラスは、Oracle拡張プロパティに対して、次のset
XXX
メソッドとget
XXX
メソッドを実装しています。
String getConnectionCacheName()
java.util.Properties getConnectionCacheProperties()
void setConnectionCacheProperties(java.util.Properties cp)
java.util.Properties getConnectionProperties()
void setConnectionProperties(java.util.Properties cp)
注意: setConnectionProperties メソッドを使用して接続のプロパティを設定し、setConnectionCacheProperties メソッドを使用して接続キャッシュのプロパティを設定します。
接続のプロパティの詳細は、「サポートされている接続プロパティ」を参照してください。 接続キャッシュのプロパティの詳細は、「接続キャッシュ・プロパティ」を参照してください。 |
boolean getConnectionCachingEnabled()
void setImplicitCachingEnabled()
String getDriverType()
void setDriverType(String dt)
String getURL()
void setURL(String url)
String getTNSEntryName()
void setTNSEntryName(String tns)
boolean getNativeXA()
void setNativeXA(boolean nativeXA)
String getONSConfiguration()
void setONSConfiguration(String onsConfig)
サーバー側内部ドライバを使用している場合、つまりdriverType
プロパティがkprb
に設定されている場合、その他のプロパティ設定は無視されます。
JDBC ThinドライバまたはOCIドライバを使用している場合は、次の点に注意してください。
URL設定には、次の例のようにuser
とpassword
の設定が含まれることがあります。この場合は、この設定が個々のuser
およびpassword
プロパティ設定よりも優先されます。
jdbc:oracle:thin:scott/tiger@localhost:1521:orcl
user
とpassword
は、URL設定を介して直接設定するか、またはgetConnection
コールを介して設定する必要があります。getConnection
コールによるuser
とpassword
の設定は、他のプロパティ設定よりも優先されます。
url
プロパティを設定した場合は、tnsEntry
、driverType
、portNumber
、networkProtocol
、serverName
およびdatabaseName
プロパティ設定は無視されます。
tnsEntry
プロパティを設定した場合(url
プロパティは設定されていないものとします)、databaseName
、serverName
、portNumber
およびnetworkProtocol
の各設定は無視されます。
OCIドライバを使用しているときに(driverType
プロパティはoci
に設定されているものとします)、networkProtocol
がipc
に設定されている場合、他のプロパティ設定は無視されます。
またgetConnectionCacheName()
は、データ・ソースのキャッシュが有効になった後でデータ・ソースのConnectionCacheName
プロパティが設定された場合にのみキャッシュの名前を戻します。
この項では、JNDI機能を使用せずにデータベースに接続する場合の、データソースの最も基本的な使用例を示します。ベンダーによってはベンダー固有のハードコードされたプロパティ設定が必要であることに注意してください。
次の例のようにOracleDataSource
インスタンスを作成し、必要に応じて接続プロパティを初期化して、接続インスタンスを取得します。
OracleDataSource ods = new OracleDataSource(); ods.setDriverType("oci"); ods.setServerName("dlsun999"); ods.setNetworkProtocol("tcp"); ods.setDatabaseName("816"); ods.setPortNumber(1521); ods.setUser("scott"); ods.setPassword("tiger"); Connection conn = ods.getConnection();
または、必要に応じて次のようにユーザー名とパスワードをオーバーライドします。
Connection conn = ods.getConnection("bill", "lion");
この項では、データソースを使用してデータベースに接続する場合のJNDI機能を示します。ベンダー固有のハードコードされたプロパティ設定は、データソース・インスタンスをJNDI論理名にバインドするコードの部分でのみ必要になります。これ以降は、接続インスタンスを取得するデータソースを作成するために、論理名を使用して、移植可能なコードを作成できます。
注意: データソースの作成と登録は、一般にJDBCアプリケーションではなく、JNDI管理者によって処理されます。 |
データソース・プロパティの初期化
次の例に示すように、OracleDataSource
インスタンスを作成し、必要に応じてそのプロパティを初期化します。
OracleDataSource ods = new OracleDataSource(); ods.setDriverType("oci"); ods.setServerName("dlsun999"); ods.setNetworkProtocol("tcp"); ods.setDatabaseName("816"); ods.setPortNumber(1521); ods.setUser("scott"); ods.setPassword("tiger");
前述の例で示したように、OracleDataSource
インスタンスods
の接続プロパティを初期化した後は、次の例に示すように、このデータソース・インスタンスをJNDIに登録できます。
Context ctx = new InitialContext(); ctx.bind("jdbc/sampledb", ods);
JNDI InitialContext()
コンストラクタをコールすると、初期JNDIネーミング・コンテキストを参照するJavaオブジェクトが作成されます。表示されていないシステム・プロパティによって、使用するサービス・プロバイダがJNDIに指示されます。
ctx.bind
コールは、OracleDataSource
インスタンスを論理JNDI名にバインドします。つまり、ctx.bind
をコールした後、いつでも論理名jdbc/sampledb
を使用して、OracleDataSource
インスタンスods
のプロパティによって記述されるデータベースへの接続をオープンできます。論理名jdbc/sampledb
は、このデータベースに論理的にバインドされます。
JNDIネームスペースの階層構造は、ファイル・システムの階層構造と似ています。この例で、JNDI名はルート・ネーミング・コンテキストでサブコンテキストjdbc
を指定し、jdbc
サブコンテキスト内で論理名sampledb
を指定します。
Context
インスタンスとInitialContext
クラスは、標準javax.naming
パッケージ内にあります。
注意: JDBC 2.0仕様では、すべてのJDBCデータソースを、JNDIネームスペースのjdbc ネーミング・サブコンテキスト、またはjdbc サブコンテキストの子サブコンテキストに登録する必要があります。 |
lookupを実行して、JNDI名に論理的にバインドされたデータベースへの接続をオープンするには、論理JNDI名を使用します。これを実行するには、lookupの結果(Java Object
も可)をOracleDataSource
にキャストし、そのgetConnection
メソッドを使用して接続をオープンします。
OracleDataSource odsconn = (OracleDataSource)ctx.lookup("jdbc/sampledb"); Connection conn = odsconn.getConnection();
SYS
でログオンするためのロールを指定するには、internal_logon
接続プロパティを使用します。SYS
でログオンするには、internal_logon
接続プロパティを、SYSDBA
またはSYSOPER
に設定します。
注意: ロールを指定する機能は、sys ユーザー名にのみサポートされます。 |
Bequeathed接続の場合、internal_logon
プロパティを設定することにより、SYS
として接続を取得できます。リモート接続の場合、追加でパスワード・ファイルの設定手順を実行する必要があります。
JDBC ThinドライバがデータベースにSYSDBA
として接続するためには、ユーザーを構成する必要があります。これは、Oracle Databaseのセキュリティ・システムでは、リモート接続用に管理者としてのパスワード・ファイルが必要なためです。次の手順を実行します。
orapwd
パスワード・ユーティリティを使用してサーバー側またはリモート・データベースでパスワード・ファイルを設定します。ユーザーsys
のパスワード・ファイルを追加するには、次のようにします。
UNIXの場合
orapwd file=$ORACLE_HOME/dbs/orapw entries=200
Enter password: password
Microsoft Windowsの場合
orapwd file=%ORACLE_HOME%\database\PWDsid_name
.ora entries=200
Enter password: password
file
は、パスワード・ファイルの名前と同じである必要があります。password
は、ユーザーSYS
のパスワードです。これは、SQL PlusでALTER USER
文を使用することにより変更可能です。entries
は、見積りのエントリ数よりも高い値に設定してください。
パスワード・ファイル名の構文は、Microsoft WindowsとUNIXでは異なります。
関連項目: 『Oracle Database管理者ガイド』 |
sysdba
としてリモート・ログインを有効にします。この手順では、SYSDBA
およびSYSOPER
システム権限を個別のユーザーに付与し、それらのユーザーがそのままのユーザーとして接続できるようにします。
データベースを停止し、次の行を、UNIXの場合はinit
service_name
.ora
に、Microsoft Windowsの場合はinit.ora
に追加します。
remote_login_passwordfile=exclusive
init
service_name
.ora
ファイルは、ORACLE_HOME
/dbs/
およびORACLE_HOME
/admin/db_name/pfile/
に存在します。これらの2つのファイルは同期化してください。
init.ora
ファイルは、%ORACLE_BASE%\ADMIN\db_name\pfile\
に存在します。
SYS
ユーザーのパスワードを変更します。これは、オプションの手順です。
PASSWORD sys Changing password for sys New password: password Retype new password: password
SYS
がSYSDBA
権限を持っていることを確認します。
SQL> select * from v$pwfile_users; USERNAME SYSDB SYSOP ---------------------- --------- --------- SYS TRUE TRUE
リモート・データベースを再起動します。
例8-1 リモート接続でのSYSログインの使用
//This example works regardless of language settings of the database. /** case of remote connection using sys **/ import java.sql.*; import oracle.jdbc.*; import oracle.jdbc.pool.*; // create an OracleDataSource OracleDataSource ods = new OracleDataSource(); // set connection properties java.util.Properties prop = new java.util.Properties(); prop.put("user", "sys"); prop.put("password", "sys"); prop.put("internal_logon", "sysoper"); ods.setConnectionProperties(prop); // set the url // the url can use oci driver as well as: // url = "jdbc:oracle:oci8:@inst1"; the inst1 is a remote database String url = "jdbc:oracle:thin:@//myHost:1521/service_name"; ods.setURL(url); // get the connection Connection conn = ods.getConnection(); ...
次の例は、SYS
ログインを指定するための、internal_logon
およびSYSDBA
引数の使用方法を示しています。この例は、データベースの各国語設定に関係なく動作します。
/** Example of bequeath connection **/ import java.sql.*; import oracle.jdbc.*; import oracle.jdbc.pool.*; // create an OracleDataSource instance OracleDataSource ods = new OracleDataSource(); // set neccessary properties java.util.Properties prop = new java.util.Properties(); prop.put("user", "sys"); prop.put("password", "sys"); prop.put("internal_logon", "sysdba"); ods.setConnectionProperties(prop); // the url for bequeath connection String url = "jdbc:oracle:oci8:@"; ods.setURL(url); // retrieve the connection Connection conn = ods.getConnection(); ...
接続プロパティの一部は、Oracleパフォーマンス拡張要素で使用します。これらのプロパティの設定は、次のようにOracleConnection
オブジェクトで対応するメソッドを使用することと等価です。
defaultRowPrefetch
プロパティの設定は、setDefaultRowPrefetch
のコールと等価です。
remarksReporting
プロパティの設定は、setRemarksReporting
のコールと等価です。
defaultBatchValue
プロパティの設定は、setDefaultExecuteBatch
コールと等価です。
例
次の例は、java.util.Properties
クラスのput
メソッドの使用方法を示します。この例では、Oracleパフォーマンス拡張要素のパラメータを設定する方法を示します。
//import packages and register the driver import java.sql.*; import java.math.*; import oracle.jdbc.*; import oracle.jdbc.pool.OracleDataSource; //specify the properties object java.util.Properties info = new java.util.Properties(); info.put ("user", "scott"); info.put ("password", "tiger"); info.put ("defaultRowPrefetch","20"); info.put ("defaultBatchValue", "5"); //specify the datasource object OracleDataSource ods = new OracleDataSource(); ods.setURL("jdbc:oracle:thin:@//myhost:1521/orcl"); ods.setUser("scott"); ods.setPassword("tiger"); ods.setConnectionProperties(info); ...
データベースURLは文字列です。完全なURL構文は、次のとおりです。
jdbc:oracle:driver_type:[username/password]@database_specifier
注意:
|
URLの最初の部分では、使用するJDBCドライバを指定します。サポートされているdriver_type
値は、thin
、oci
およびkprb
です。
URLの残りの部分には、オプションでユーザー名とパスワードをスラッシュ、@およびデータベース指定子で区切って指定します。このデータベース指定子は、アプリケーションが接続するデータベースを一意に識別します。一部のデータベース指定子は、JDBC Thinドライバ専用またはJDBC OCIドライバ専用です。両方に使用できる指定子もあります。
データベース指定子
表8-3に、データベース指定子と各指定子がサポートするJDBCドライバを示します。
注意:
|
表8-3 サポートされるデータベース指定子
指定子 | サポートするドライバ | 例 |
---|---|---|
Oracle Net接続記述子 |
Thin、OCI |
Thinの場合。アドレス・リストを使用します。 url="jdbc:oracle:thin:@(DESCRIPTION= (LOAD_BALANCE=on) (ADDRESS_LIST= (ADDRESS=(PROTOCOL=TCP)(HOST=host1) (PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=host2)(PORT=1521))) (CONNECT_DATA=(SERVICE_NAME=service_name)))" OCIの場合。クラスタを使用します。 "jdbc:oracle:oci:@(DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=cluster_alias) (PORT=1521)) (CONNECT_DATA=(SERVICE_NAME=service_name)))" |
Thin形式のサービス名 |
Thin |
詳細は、「Thin形式のサービス名の構文」を参照してください。 "jdbc:oracle:thin:scott/tiger@//myhost:1521/myservicename" |
LDAP構文 |
Thin |
詳細は、LDAP構文を参照してください。 |
Bequeathed接続 |
OCI |
空。つまり、@の後には何も記述しません。 "jdbc:oracle:oci:scott/tiger/@" |
TNSNames別名 |
Thin、OCI |
詳細は、「TNSNames別名の構文」を参照してください。 |
Thin形式のサービス名の構文
Thin形式のサービス名は、JDBC Thinドライバでのみサポートされます。構文は、次のとおりです。
@//host_name:port_number/service_name
たとえば、次のようになります。
jdbc:oracle:thin:scott/tiger@//myhost:1521/myservicename
TNSNames別名の構文
接続元のクライアント・コンピュータ上のtnsnames.ora
ファイルにリストされた、利用可能なTNSNAMES
エントリを検索できます。Windowsの場合、このファイルはORACLE_HOME
\NETWORK\ADMIN
ディレクトリにあります。UNIXシステムの場合は、ORACLE_HOME
ディレクトリ、またはTNS_ADMIN
環境変数に示されているディレクトリに格納されています。
たとえば、ホストmyhost
上のデータベースに、ユーザーscott
、パスワードtiger
(MyHostString
のTNSNAMES
エントリを持つ)で接続する場合は、次のように記述します。
OracleDataSource ods = new OracleDataSource(); ods.setTNSEntryName("MyTNSAlias"); ods.setUser("scott"); ods.setPassword("tiger"); ods.setDriverType("oci"); Connection conn = ods.getConnection();
JDBC Thinドライバがtnsnames.ora
ファイルの位置を確認できるように、oracle.net.tns_admin
システム・プロパティをtnsnames.ora
ファイルの位置に設定する必要があります。たとえば、次のようになります。
System.setProperty("oracle.net.tns_admin", "c:\\Temp"); String url = "jdbc:oracle:thin:@tns_entry";
注意: TNSNamesをJDBC Thinドライバとともに使用する場合は、oracle.net.tns_admin プロパティをtnsnames.ora ファイルのあるディレクトリに設定する必要があります。
java -Doracle.net.tns_admin=$ORACLE_HOME/network/admin |
Lightweight Directory Access Protocol(LDAP)構文を使用するデータベース指定子の例を次に示します。
"jdbc:oracle:thin:@ldap://ldap.acme.com:7777/sales,cn=OracleContext,dc=com"
SSLを使用する場合は、これを次のように変更します。
"jdbc:oracle:thin:@ldaps://ldap.acme.com:7777/sales,cn=OracleContext,dc=com"
注意: JDBC Thinドライバの場合、データベース指定子のldap: をldaps: に置き換えると、LDAPを使用し、SSLを介してOracle Internet Directoryと通信できます。LDAPサーバーは、SSLを使用するように構成されている必要があります。構成されていない場合は、接続に失敗します。 |
JDBC Thinドライバは、サービス名の解決時にLDAPサーバー・リストのフェイルオーバーをサポートします。ハードウェア・ロード・バランサは必要ありません。また、LDAPサーバーへの接続についてはクライアント側ロード・バランシングもサポートされます。フェイルオーバーおよびロード・バランシングをサポートするため、空白で区切られたLDAP URL構文のリストが使用されます。
LDAP URLのリストを指定すると、フェイルオーバーとロード・バランシングの両方がデフォルトで有効になります。oracle.net.ldap_loadbalance
接続プロパティを使用するとロード・バランシングを無効にでき、oracle.net.ldap_failover
接続プロパティを使用するとフェイルオーバーを無効にできます。
フェイルオーバーを使用するが、クライアント側ロード・バランシングを無効にする例を次に示します。
Properties prop = new Properties(); String url = "jdbc:oracle:thin:@ldap://ldap1.acme.com:3500/cn=salesdept,cn=OracleContext,dc=com/salesdb " + "ldap://ldap2.acme.com:3500/cn=salesdept,cn=OracleContext,dc=com/salesdb " + "ldap://ldap3.acme.com:3500/cn=salesdept,cn=OracleContext,dc=com/salesdb"; prop.put("oracle.net.ldap_loadbalance", "OFF" ); OracleDataSource ods = new OracleDataSource(); ods.setURL(url); ods.setConnectionProperties(prop);
JDBC ThinドライバはLDAP非匿名バインドをサポートします。データソースに対して、認証情報を含む一連のJNDI環境プロパティを指定できます。LDAPサーバーが匿名バインドを許可しないよう設定されている場合は、LDAPサーバーに接続するために認証情報を提供する必要があります。次の例は、簡単なクリアテキストのパスワード認証を示しています。
String url = "jdbc:oracle:thin:@ldap://ldap.acme.com:7777/sales,cn=salesdept,cn=OracleContext,dc=com"; Properties prop = new Properties(); prop.put("java.naming.security.authentication", "simple"); prop.put("java.naming.security.principal","cn=salesdept,cn=OracleContext,dc=com"); prop.put("java.naming.security.credentials", "mysecret"); OracleDataSource ods = new OracleDataSource(); ods.setURL(url); ods.setConnectionProperties(prop);
JDBCは3つのプロパティをJNDIに渡すため、クライアントによって選択される認証メカニズムは、JNDIでのそれらのプロパティの解釈方法に対応しています。たとえば、クライアントがjava.naming.security.authentication
プロパティを明示的に指定せずに認証情報を指定した場合、デフォルト認証メカニズムは単純となります。詳細は、関連するJDNIドキュメントを参照してください。