JDBCでのデータベース操作

JDBCでのデータベース操作の一般的な側面をいくつか示します。

基本的なSQL文の実行

ConnectionインスタンスのcreateStatement()メソッド、およびStatementインスタンスのexecuteUpdate()メソッドまたはexecuteQuery()メソッドを使用すると、Javaアプリケーション内でSQL文を実行できます。

『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』TimesTenデータベース内のデータの操作を参照してください。

事前に文が準備されていない場合は、SQL文の特性および返された結果セットに応じて、execute()executeUpdate()executeQuery()などのStatementオブジェクトの実行メソッドを使用します。

事前に準備されたSQL文には、PreparedStatementオブジェクトの同じ実行メソッドを使用します。

execute()メソッドは、結果セットがある場合はtrueを返し(SELECTなど)、結果セットがない場合はfalseを返します(INSERTUPDATEDELETEなど)。executeUpdate()メソッドは、影響を受ける行数を返します。たとえば、INSERT文を実行すると、executeUpdate()メソッドは挿入された行数を返します。executeQuery()メソッドは結果セットを返すため、(SELECT文の実行時など)結果セットが必要な場合にのみコールする必要があります。

ノート:

  • 通常、StatementPreparedStatementまたはCallableStatementのメソッドclose()を使用して、使用が終わった文をクローズします。TimesTen文セットはまた、java.lang.AutoCloseableを使用した標準のtry-with-resource機能もサポートしています。

  • 「TimesTen結果セットの使用: ヒントおよび制限」を参照してください。

この例では、StatementオブジェクトでexecuteUpdate()メソッドを使用して、現在のスキーマのcustomer表にデータを挿入するINSERT文を実行します。示されてはいませんが、この接続はオープンされている必要があります。

Connection conn = null;
Statement stmt = null;
...
// [Code to open connection. See Connecting to the Database...] 
...
try {
    stmt = conn.createStatement();
    int numRows = stmt.executeUpdate("insert into customer values" 
                  + "(40, 'West', 'Big Dish', '123 Signal St.')");
}
catch (SQLException ex) {
    ...
}

次の例では、StatementオブジェクトでexecuteQuery()コールを使用し、現在のスキーマのcustomer表にSELECT文を実行して、返されたjava.sql.ResultSetインスタンスを表示します。

Statement stmt = null;
. . . . . .
try {
  ResultSet rs = stmt.executeQuery("select cust_num, region, " +
                      "name, address from customer");
  System.out.println("Fetching result set...");
  while (rs.next()) {
    System.out.println("\n Customer number: " + rs.getInt(1));
    System.out.println(" Region: " + rs.getString(2));
    System.out.println(" Name: " + rs.getString(3));
    System.out.println(" Address: " + rs.getString(4));
    }
  } 
catch (SQLException ex) {
  ex.printStackTrace();
}

データベースに対するコミットまたは変更のロールバック

この項では、自動コミットおよび手動コミット、またはロールバックについて説明します(JDBC ConnectionオブジェクトをmyconnStatementオブジェクトをmystmtと仮定しています)。次の内容を含みます。

ノート:

接続時のすべてのオープン・カーソルは、TimesTenでのトランザクションのコミットまたはロールバック時にクローズされます。

『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』トランザクションの概要を参照してください。

自動コミットの設定

TimesTen接続は、デフォルトで自動コミットが有効になっていますが、パフォーマンス上の理由で無効にすることをお薦めします。ConnectionメソッドsetAutoCommit()を使用して、自動コミットの有効/無効を切り替えることができます。

次のように自動コミットを無効にします。

myconn.setAutoCommit(false);
// Report any SQLWarnings on the connection.
// See Reporting Errors and Warnings.

ノート:

setAutoCommit()コールでは、そのコールにより実際に自動コミット設定が変更された場合にのみコミットが発生します。

手動でのコミットまたは変更のロールバック

自動コミットが無効化された場合、Connectionメソッドcommit()を使用して手動でトランザクションをコミットするか、またはrollback()メソッドを使用して変更をロールバックする必要があります。次の例を想定してください。

myconn.commit();

または:

myconn.rollback();

SQLのCOMMIT文およびROLLBACK SQL文の使用

SQLのCOMMIT文およびROLLBACK文は、他のSQL文と同様に準備して実行できます。COMMIT文およびROLLBACK文の使用は、Connectionメソッドcommit()およびrollback()の使用と同じ結果になります。

例:

mystmt.execute("COMMIT");

複数スレッドの管理

アプリケーションにデータベースに対する直接接続がある場合、TimesTenファンクションはアプリケーションとスタック空間を共有します。マルチスレッド環境では、デバッグが困難な予測不能な状態でプログラムが失敗する可能性があるため、各スレッドに割り当てたスタックが超過しないようにすることが重要です。 TimesTenのコールが消費するスタック空間は、使用するSQLの機能によっても異なります。ほとんどのアプリケーションでは、スレッド・スタック空間を34 KBから72 KBの間で設定する必要があります。

各スレッドに割り当てられるスタック空間の量は、スレッドの作成時にオペレーティング・システムが指定します。Windowsでは、TimesTenデバッグ・ドライバを使用し、Visual C++デバッグCライブラリとアプリケーションをリンクすると、スレッドが割当て量よりもそのスタックを拡張しようとするときに識別可能な例外を発生させる、スタック・プローブが有効になります。

ノート:

マルチスレッド・アプリケーションでは、同じデータベースへの様々な接続ハンドルにリクエストを発行するスレッドで、それ自身とのロック競合が発生する可能性があります。TimesTenは、この状況でロック・タイムアウトおよびデッドロック・エラーを返します。

level4サンプル・アプリケーションでは、複数スレッドの使用について説明します。「TimesTenクイック・スタートおよびサンプル・アプリケーションについて」を参照してください。

Javaのエスケープ構文およびSQLファンクション

JDBCでSQLを使用する際は、Javaエスケープ構文に特に注意します。UNISTRなどのSQLファンクションは、バックスラッシュ文字(\)を使用します。バックスラッシュ文字は、エスケープする必要があります。

たとえば、Javaアプリケーションで次のSQL構文を使用すると、意図した結果にならない場合があります。

INSERT INTO table1 SELECT UNISTR('\00E4') FROM dual;

バックスラッシュ文字を次のようにエスケープします。

INSERT INTO table1 SELECT UNISTR('\\00E4') FROM dual;