Skip to main content

This documentation is for an older version of this product. See the latest version of this content.Opens in a new tab

JDBC ドライバの使用法

この章では、アプリケーションと InterSystems IRIS 間で JDBC 接続を確立する方法と、JDBC ドライバの拡張メソッドとプロパティを使用する方法について説明します。

"Connecting Your Application to InterSystems IRISOpens in a new tab" にも、サンプル・コードを含め、JDBC を使用して Java アプリケーションから InterSystems IRIS サーバに接続する手順が示されています。

JDBC 接続の確立

このセクションでは、DriverManager または DataSource を使用して接続を確立および制御する方法について説明します。

JDBC 接続 URL の定義

java.sql.Connection URL は、アクセス先のホスト・アドレス、ポート番号、およびネームスペースに関する情報を持つ接続を提供します。InterSystems JDBC ドライバでは、オプションの URL パラメータもいくつか使用できます。

必須の URL パラメータ

最小限必要な URL 構文は以下のとおりです。

   jdbc:IRIS://<host>:<port>/<namespace>

ここで、必須パラメータは以下のように定義されます。

  • host — IP アドレス、または完全修飾ドメイン名 (FQDN)。例えば、127.0.0.1localhost は両方ともローカル・マシンを表します。

  • port — InterSystems IRIS スーパーサーバが待ち受け状態にある TCP ポート番号。既定値は 1972 です。詳細は、"構成パラメータ・ファイル・リファレンス" の "DefaultPort" を参照してください)。

  • namespace — アクセス先の InterSystems IRIS ネームスペース。

例えば、以下の URL では、host127.0.0.1port1972namespaceUser に指定されます。

   jdbc:IRIS://127.0.0.1:1972/User

オプションの URL パラメータ

hostport、および namespace に加えて、オプションの URL パラメータをいくつか指定することもできます。完全な構文は、以下のとおりです。

   jdbc:IRIS://<host>:<port>/<namespace>/<logfile>:<eventclass>:<nodelay>:<ssl>

ここで、オプションのパラメータは以下のように定義されます。

  • logfile — JDBC ログ・ファイルを指定します (“JDBC のログ” を参照してください)。

  • eventclass — この IRISDataSource オブジェクトにトランザクション・イベント・クラスを設定します。

  • nodelayIRISDataSource オブジェクト経由で接続している場合に TCP_NODELAY オプションを設定します。このフラグを切り替えると、アプリケーションのパフォーマンスに影響する場合があります。有効な値は、true および false です。設定されていない場合、既定値として true が設定されます。

  • sslIRISDriverIRISDataSource の両方で TLS を有効にします ("セキュリティ管理ガイド" の “構成について” を参照)。有効な値は、true および false です。設定されていない場合、既定値として false が設定されます。

これらのオプションの URL パラメータは、他のパラメータを指定しなくても、それぞれ個別に定義できます。例えば、以下の URL は、必須のパラメータと nodelay オプションのみを設定します。

   jdbc:IRIS://127.0.0.1:1972/User/::false

他の接続プロパティを指定するには、Properties オブジェクト内の DriverManager に渡します (“接続のための DriverManager の使用法” を参照してください)。

接続のための IRISDataSource の使用法

com.intersystems.jdbc.IRISDataSource を使用してドライバをロードした後、java.sql.Connection オブジェクトを作成します。これは、データベースに接続する推奨のメソッドで、InterSystems IRIS で完全にサポートされています。

IRISDataSource との接続の開き方

以下の例では、ドライバをロードしてから IRISDataSource を使用して接続を作成し、ユーザ名およびパスワードを指定します。

  try{
    IRISDataSource ds = new IRISDataSource();
    ds.setURL("jdbc:IRIS://127.0.0.1:1972/User");
    ds.setUser("_system");
    ds.setPassword("SYS");
    Connection dbconnection = ds.getConnection();
  }
catch (SQLException e){
  System.out.println(e.getMessage());
}
catch (ClassNotFoundException e){
  System.out.println(e.getMessage());
}

この例では、意図的に localhost ではなくリテラル・アドレス 127.0.0.1 を使用します。ホスト名が Ipv4 と Ipv6 で同じように解決されるシステムでは、localhost を使用する場合、Java は Ipv6 経由で接続しようとします。

Note:

IRISDataSource クラスは、接続プロパティ・アクセサの拡張セットを提供します (この例では、setURL()setUser()setPassword() など)。アクセサの完全なリストについては、クイック・リファレンスの “IRISDataSource クラス”、およびすべての接続プロパティの詳細は、このリファレンスの後半にある “接続パラメータのオプション” を参照してください。

接続のための DriverManager の使用法

DriverManager クラスは、接続を作成するためにも使用できます。以下のコードは、その方法の一例です。

Class.forName ("com.intersystems.jdbc.IRISDriver").newInstance();
   String  url="jdbc:IRIS://127.0.0.1:1972/User";
   String  username = "_SYSTEM";
   String  password = "SYS";
   dbconnection = DriverManager.getConnection(url,username,password);

以下のコードに示すように、DriverManager の接続プロパティを Properties オブジェクトで指定することもできます。

String  url="jdbc:IRIS://127.0.0.1:1972/User";
   java.sql.Driver drv = java.sql.DriverManager.getDriver(url);

   java.util.Properties props = new Properties();
   props.put("user",username);
   props.put("password",password);
   java.sql.Connection dbconnection = drv.connect(url, props);

利用できるプロパティの詳細なリストは、このリファレンスの後半にある “接続パラメータのオプション” を参照してください。

バルク挿入のための列方向のバインディング

JDBC では、事前入力されたデータのバルク挿入は通常、addBatch() をループで呼び出すことによって実行されます。これは、データが既に配列内にあり、サーバに送信する準備ができている場合には最適ではありません。InterSystems IRIS は、ループをバイパスして、配列全体を 1 つの setObject() 呼び出しで渡すことができる拡張機能を提供します。

例えば、一般的なコードは、以下のように各項目に対して setObject() を呼び出します。

// Typical AddBatch() loop
  for (int i=0;i<10000;i++){
    statement.setObject(1,objOne);
    statement.setObject(2,objTwo);
    statement.setObject(3,objThree);
    statement.addBatch();
  }
  statement.executeBatch();

すべての項目を 1 つの Object 配列に読み込んで、配列全体を 1 つの呼び出しで追加すれば、コードはより高速かつ単純になります。

// Adding an ArrayList named objArray with a single call
  IRISPreparedStatement.setObject(objArray);
  statement.addBatch();
  statement.executeBatch();

列方向のバインディングでは、arraylist としてバインドされた最初のパラメータが、その arraylist のサイズ (複数存在する場合) を使用してバッチ内の行数を表すことが前提となります。arraylist としてバインドされたその他のパラメータは、同じサイズであるか、または 1 つの値のみ (ユーザ定義の既定値など) を指定している必要があります。そうでない場合、addbatch() の呼び出し時に、"列方向のパラメータ値が一致しません : #rows 行が予期されていましたが、# parameter! で見つかったのは #count だけです。" という例外がスローされます。

例えば、3 つのパラメータと 10 個の行をバインドする場合、パラメータ 1 で 10 個の値を arraylist にバインドできます。パラメータ 2 と 3 には同様に arraylist で 10 個の値を指定するか、1 つの値のみを指定する (すべての行に 1 つの既定値を指定する場合) 必要があります。すべてを入力するか、1 つのみ入力する必要があります。それ以外では例外がスローされます。

以下に、行方向のバインディングと列方向のバインディングで同じ操作を行う例を示します。

bindRowWise()
public static void bindRowWise() throws Exception {
  int rowCount = cName.size();
  String insert = "INSERT INTO CUSTOMER VALUES(?,?,?,?)";
  try {
    PreparedStatement ps = conn.prepareStatement(insert);
    for (int i=0;i<rowCount;i++){
      ps.setObject(1,cName.get(i));
      ps.setObject(2,cAddress.get(i));
      ps.setObject(3,cPhone.get(i));
      ps.setObject(4,cAcctBal.get(i));
      ps.addBatch();
    }
    ps.executeBatch();
  }
  catch (Exception e) {
    System.out.println("\nException in RowBinding()\n"+e);
  }

} // end bindRowWise()
bindColumnWise()
public static void bindColumnWise() throws Exception {
  String insert = "INSERT INTO CUSTOMER VALUES(?,?,?,?)";
  try {
    PreparedStatement ps = conn.prepareStatement(insert);
    ps.setObject(1, new ArrayList<>(cName)    );
    ps.setObject(2, new ArrayList<>(cAddress) );
    ps.setObject(3, new ArrayList<>(cPhone)   );
    ps.setObject(4, new ArrayList<>(cAcctBal) );
    ps.addBatch();
    ps.executeBatch();
  catch (Exception e) {
    System.out.println("\nException in bindColumnWise()\n"+e);
  }
} // end bindColumnWise()

接続プーリング

IRISConnectionPoolDataSource メソッドの使用法

IRISConnectionPoolDataSource クラスは、ConnectionPoolDataSource を実装し、プールされた接続のテストと監視に役立つ一連の独自の拡張機能によってそれを拡張したものです。以下の拡張機能を使用できます。

  • getConnectionWaitTimeout() 接続プール・マネージャが、接続が利用可能になるまで待機する秒数を返します。

  • getMaxPoolSize() 許可される接続の最大数を返します。

  • getPoolCount() 接続プール内の現在のエントリ数を返します。

  • restartConnectionPool() 物理接続をすべて切断し、接続プールを空にします。

  • setMaxPoolSize() プール内で許可される接続の最大数を指定する int 値を取ります。既定値は 40 です。

  • setConnectionWaitTimeout() 接続の待機タイムアウト間隔を秒数で指定する int 値を取ります。タイムアウト時間が過ぎても利用可能な接続がない場合は、例外がスローされます。既定では 0 に設定されています。これは、接続が即時に利用可能になることを示します。プールがいっぱいである場合は例外がスローされます。

IRISConnectionPoolDataSource クラスは、IRISDataSource に実装された独自の拡張機能も継承します (クイック・リファレンスの “接続パラメータのオプション” を参照)。

InterSystems IRIS でこのクラスを使用する手順は次のとおりです。

  1. 必要なパッケージをインポートします。

    import com.intersystems.jdbc.*;
    import java.sql.*;
    
  2. IRISConnectionPoolDataSource オブジェクトをインスタンス化します。reStart() メソッドを使用して物理接続をすべて切断し、プールを空にします。setURL() (IRISDataSource から継承) を使用して、プールの接続にデータベース URL ("JDBC 接続 URL の定義" を参照) を設定します。

    IRISConnectionPoolDataSource pds = new IRISConnectionPoolDataSource();
       pds.restartConnectionPool();
       pds.setURL("jdbc:IRIS://127.0.0.1:1972/User");
       pds.setUser("_system");
       pds.setPassword("SYS");
    
  3. 最初は、getPoolCount() は 0 を返します。

    System.out.println(pds.getPoolCount()); //outputs 0.
    
  4. getConnection() を使用して、プールからデータベース接続を取得します。

    Connection dbConnection = pds.getConnection();
    
    Caution:

    InterSystems JDBC ドライバ接続は、常に IRISDataSourcegetConnection() メソッドを呼び出して取得する必要があります。このメソッドは、自動の透過的な接続プーリングを提供するために拡張されています。ConnectionPoolDataSource.getPooledConnection() メソッドは、JDBC 標準で要求されているため実装されていますが、直接呼び出してはなりません。

  5. 接続を切断します。getPoolCount() が 1 を返すようになります。

    dbConnection.close();
    System.out.println(pds.getPoolCount()); //outputs 1
    

最適化とテストのオプション

このセクションには、開発およびテストの際に役立つ可能性のある専用の情報が含まれています。

  • JDBC のログ — JDBC アプリケーションをテストする際にログを有効にする方法を説明します。

  • 共有メモリ接続 — サーバとクライアントが同じマシン上にある場合に接続がどのように機能するかについて説明します。

  • 文のプーリング — 文を初めて使用するときに、最適化された文をキャッシュに格納する方法について説明します。

JDBC のログ

アプリケーションで問題が発生した場合、ログを有効にしてアプリケーションを監視できます。アプリケーションを実行し、エラー条件をトリガしたことを確認した後、エラー・メッセージや、異常な活動のすべてのログ記録をチェックします。エラーの原因は通常、メッセージ内に表れています。

Note:

ログは、トラブルシューティングを実行する必要がある場合のみ有効にします。ログを有効にするとパフォーマンスが大幅に低下するため、通常の操作時は有効にしないでください。

InterSystems IRIS に接続するときに JDBC のログを有効にするには、JDBC 接続文字列の末尾にログ・ファイル名を追加します。接続時に、ドライバによってアプリケーションの作業ディレクトリに保存されるログ・ファイルが保存されます。

例えば、元の接続文字列が以下であるとします。

   jdbc:IRIS://127.0.0.1:1972/USER

ログを有効にするには、この文字列を以下のように変更して再接続します。

   jdbc:IRIS://127.0.0.1:1972/USER/myjdbc.log

このログには、InterSystems IRIS データベースから見た対話処理が記録されます。

指定されたログ・ファイルが存在する場合、既定では新しいログ・エントリがそのファイルに追加されます。既存のファイルを削除して、新しいファイルを作成するには、接頭語としてログ・ファイル名の前にプラス (+) 文字を付けます。例えば、次の文字列では、myjdbc.log を削除し (既存の場合)、同じ名前で新しいログ・ファイルを作成します。

   jdbc:IRIS://127.0.0.1:1972/USER/+myjdbc.log

共有メモリ接続

InterSystems IRIS では、Java アプリケーションが InterSystems IRIS サーバ・インスタンスと同じマシン上で実行されている場合、TCP/IP ではなく共有メモリ接続が使用されます。このセクションでは、共有メモリが動作するしくみと、開発およびテストの目的で共有メモリを無効にする方法について説明します。

共有メモリ接続は、高いコストのかかる可能性があるカーネル・ネットワーク・スタックの呼び出しを回避して、JDBC 操作のために最適な低遅延と高スループットを実現することで、パフォーマンスを最大化します。

接続でサーバ・アドレス localhost または 127.0.0.1 が指定されている場合、既定で共有メモリが使用されます。実際のマシン・アドレスが指定されている場合は、TCP/IP が使用されます。共有メモリ・デバイスに障害が発生した場合、または共有メモリ・デバイスが利用できない場合、接続は自動的に TCP/IP にフォールバックします。

共有メモリを無効にするには、接続文字列で SharedMemory プロパティを false に設定します。以下の例では、サーバ・アドレスが 127.0.0.1 に指定されている場合でも共有メモリを使用しない接続を作成します。

  Properties props = new Properties();
  props.setProperty("SharedMemory", "false");
  props.setProperty("user", "_system");
  props.setProperty("password", "SYS");
  IRISConnection conn = (IRISConnection)DriverManager.getConnection("jdbc:IRIS://127.0.0.1:1972/USER/ ",props);

アクセサ DataSource.getSharedMemory() および DataSource.setSharedMemory() を使用して、現在の接続モードの読み取りおよび設定を行うことができます。IRISConnection.isUsingSharedMemory() メソッドを使用して、接続モードをテストすることもできます。

共有メモリは TLS または Kerberos 接続には使用されません。共有メモリ接続が試行されたかどうか、およびその接続が成功したかどうかの情報は、JDBC ログに記録されます (“JDBC のログ” を参照してください)。

Note:
共有メモリ接続はコンテナの境界を越えて機能しない

現在のところ、2 つの異なるコンテナ間の共有メモリ接続はサポートされていません。クライアントが localhost または 127.0.0.1 を使用してコンテナの境界を越えて接続を試行した場合、接続モードは既定で共有メモリになり、接続は失敗します。このことは、Docker の --network host オプションが指定されているかどうかに関係なく適用されます。サーバ・アドレスの実際のホスト名を指定するか、接続文字列で共有メモリを無効にすることで (上記の例のように)、コンテナ間の TCP/IP 接続を保証できます。

サーバとクライアントが同じコンテナにある場合は、問題なく共有メモリ接続を使用できます。

文のプーリング

JDBC 4.0 は、追加のインフラストラクチャである「文のプーリング」を追加しています。この機能により、最適化された文は、最初に使用されたときにキャッシュに格納されます。文のプールは、接続プールによって維持され、プールされた文を接続間で共有できます。実装の詳細は、ユーザに対して完全に透過的です。必要な機能を提供するかどうかはドライバで決まります。

InterSystems JDBC は、この概念が JDBC 仕様の一部になるかなり前から文のプーリングを実装していました。一方、InterSystems IRIS ドライバは、この仕様で推奨されているテクニックに類似したテクニックを使用しており、実際にプーリングを実装すると高度に最適化されます。ほとんどの実装と異なり、InterSystems JDBC は、3 つの別々の文プーリング・キャッシュを備えています。1 つは JDBC 仕様で定義されている文プーリングにほぼ相当しますが、その他の 2 つは InterSystems IRIS 特有の最適化です。必要に応じて、InterSystems JDBC 文プーリングは、ユーザに対して完全に透過的になります。

InterSystems JDBC の実装は、Statement メソッドである setPoolable() および isPoolable() を、当該の文をプールする必要があるかどうかのヒントとしてサポートします。InterSystems IRIS は、独自のヒューリスティックを使用して、3 つの文プールすべての適切なサイズを決定します。したがって、IRISConnectionPoolDataSourcemaxStatements プロパティを設定することによる文プール・サイズの制約をサポートしません。オプションの javax.sql.StatementEventListener インタフェースは同じ理由でサポートされません (また、重要ではありません)。

FeedbackOpens in a new tab