Java クラス ライブラリを使用した Actian Zen へのアクセス

このチュートリアルでは、Java クラス ライブリ(JCL)を使用して Actian Zen データベースに接続する方法を学習します。

右側の「このページの内容」では当ページで扱うトピックを示しています。

Java クラス ライブラリとは

Java クラス ライブラリ(JCL)インターフェイスは、トランザクショナル SQL インターフェイスよりも低レベルで Actian Zen データベースと対話する、オブジェクト指向の方法です。

Actian Zen を使用したアプリケーション開発で JCL を使用する利点には、次のことがあります。

  • ネイティブ言語構文によるデータベースの操作
  • NoSQL スタイルのデータベース アクセス パラダイム
  • さまざまな言語でアプリケーションへのデータベース統合が簡単

JCL のセットアップ

JCL を使用するには、.jar ファイルとプラットフォーム固有のライブラリをダウンロードし、.jar ファイルをプロジェクトで使用できるようにシステムの CLASSPATH を変更する必要があります。

プロジェクトで JCL を使用するには、以下を行う必要があります。

  • Actian Zen をインストールします。
  • 最新バージョンの JDK(Java Development Kit)がシステムにインストールされていることを確認します。
  • Java クラス ライブラリを開発環境にダウンロードして展開します。
  • システムの CLASSPATH 環境変数に JCL .jar ファイルを追加します。
  • Java アプリケーションを作成します。

JCL は標準の Java クラス ライブラリであるため、他のライブラリと同様に、アプリケーションの他の部分と統合されます。

Windows での JCL セットアップ

Zen v15 の JCL Windows SDK をダウンロードして展開します。

こちらからダウンロードできます。
https://www.agtech.co.jp/actian/support/reference/sdk/access_methods/jcl/

SDK ファイルをローカル ディレクトリに展開します。Zen-SDK-JCL-Windows 下の \bin ディレクトリに jnibtrv.dll ファイルと psql.jar ファイルがあります。

ファイルが保存されている \bin ディレクトリを PATH 環境変数に追加します。

psql.jar の絶対パスを CLASSPATH 環境変数に追加します。

Linux での JCL セットアップ

Linux バージョンの Actian Zen Enterprise Server には JCL が含まれています。Linux で別途ダウンロードする必要はありません。ただし、CLASSPATH 環境変数に .jar ファイルを含める必要があります。

Actian Zen データベースをインストールしない開発環境に JCL をインストールする必要がある場合は、次のページから Zen v15 の JCL Linux SDK をダウンロードします。
https://www.agtech.co.jp/actian/support/reference/sdk/access_methods/jcl/

ダウンロードしたファイルを /usr/local などのローカル システムに展開します。

JCL を使用するには、/usr/local/psql/lib にある .jar ファイルのパスを含めるように CLASSPATH 環境変数を更新する必要があります。

  • jpscs.jar
  • psql.jar

ターミナルを開きます。ターミナル内から、現在のユーザー アカウントの ~/.bash_profile をエディターで開きます。たとえば、次のように指定します。

nano ~/.bash_profile

CLASSPATH が、JCL .jar ファイルのパスを含めるように更新されている必要があります。次のようにエントリを更新します。JDK のバージョン番号は、お使いのシステムとは異なる場合があります。

export
CLASSPATH=".:/opt/jdk/jdk-12.0.2/lib:/usr/local/psql/lib/jpscs.jar:/usr/local/psql/lib/ppsql.jar"

source コマンドを実行するか、またはログアウトしてからログインし直して、環境を更新します。

JCL の使用

このチュートリアルでは、Java クラス ライブリ(JCL)の API を使用して Actian Zen データベースに接続する方法を学習します。データベースへの接続に必要なクラスは、pervasive.database パッケージに含まれています。

データベースに接続するには、接続文字列を定義する必要があります。接続文字列の最初の部分はプロトコルで、次のようになります。

btrv:///

パスワードのないデータベースの場合は、データベースの名前が文字列の次の部分になります。たとえば、Actian Zen は、Demodata という名前のデモンストレーション データベースと共にインストールされます。このデータベースを使用するには、接続文字列を次のようにします。

btrv:///demodata

接続文字列で留意する点は、データベース名では大文字と小文字が区別されないということです。

データベースに接続するには、まず、Session オブジェクトを返す Driver.establishSession() を呼び出して新しいセッションを作成します。次に、Session.connectToDatabase() を呼び出して接続文字列を渡すことにより、名前付きデータベースに接続します。

Session session = Driver.establishSession();
Database db = session.connectToDatabase("btrv:///demodata");

接続が成功した場合は、データベース テーブルのアクセスに使用できる Database オブジェクトが返されます。接続で問題が発生した場合は、その問題に関する情報(データベースの名前が間違っているなど)を伴って例外がスローされます。

次のコードでは、データベースへの接続を試みて、その試行が成功したかどうかを示すメッセージを出力しています。

import pervasive.database.*;
public class JCLConnect {
  public static void main(String[] args) {
    try {
      Session session = Driver.establishSession();
      Database db = session.connectToDatabase("btrv:///demodata");
      System.out.println(
          "Successfully connected to: " + db.getDataPath());
      //
      // Other actions to interact with
      // the database would go here
      //
    } catch (PsqlException exc) {
      System.err.println("Problem connecting to the database.");
      exc.printStackTrace();
    }
  }
}

Database オブジェクトはテーブルを取得するために使用され、取得後は、そのテーブル内の行を作成、取得、更新、および削除するために使用できます。次のセクションでは、データの作成について見ていきます。

JCL API の詳細については、Java クラス ライブラリを使ったプログラミングを参照してください。

Java および JCL を使用したデータの作成

このセクションでは、Actian Zen データベースで Java クラス ライブラリ(JCL)を使用する方法を学習します。

JCL を使用してデータベースやテーブルを直接作成することはできないため、Zen Control Center を使用して新しいデータベースを作成し、そのデータベースに新しいテーブルを作成します。その後で JCL を使用して、そのテーブルにデータ(行)を挿入します。

  • Zen Control Center でデータベースを作成する
  • Zen Control Center を使用してテーブルを作成する
  • JCL を使用してテーブルに行を挿入する

Zen Control Center でデータベースを作成する

JCL は、データベースおよびテーブルの作成をサポートしていません。これらのタスクは、代わりに Zen Control Center を使用して実行します。Zen Control Center でデータベースおよびテーブルの構造が作成されたら、JCL を使用してデータを操作します。

本チュートリアルの残り部分では、"ZENJCLDB" という新しいデータベースを使用します。

Zen Control Center を起動すると、次の画面が表示されます。

次に示すように、エンジン ツリー ノードの下の[データベース]を右クリックし、[新規作成]>[データベース]を選択します。

新しいデータベースに ZENJCLDB という名前を付け、データベースの適切な場所を選択します(この例では、C:\actian\databases を使用します)。残りのオプションは、デフォルトの設定のままにしておきます。

完了]をクリックすると、Zen Control Center によってデータベース ファイルが作成されます。

Zen Control Center を使用してテーブルを作成する

JCL を使用してテーブルを直接作成することはできないため、再度 Zen Control Center を使用して、ZENJCLDB データベースのテーブルを作成します。

ツリーの ZENJCLDB ノードの下の[テーブル]を右クリックし、[新規作成]>[テーブル]を選択して、このデータベースに新しいテーブルを追加します。

テーブル名には Course を使用します。

JCL 経由でデータベースにアクセスする際は、テーブル、列などの名前の大文字と小文字が区別されるので、名前付けをするときはそのことに留意してください。

完了]をクリックします。Zen Control Center に列エディターのペインが表示されます。このペインを使用して、Course テーブルの列を作成および構成します。

このテーブルに次のような 4 つの列を作成します。次の表は、4 つの列とその属性を示します。列名の大文字と小文字が正しいことを確認してください。

列名

データ型

サイズ

ヌル

大小文字無視

デフォルト

ID

CHAR

6

ヌル不可(オフ)

大文字小文字を区別しない(オン)

なし

Description

CHAR

20

ヌル許可(オン)

大文字小文字を区別しない(オン)

なし

Credit

USMALLINT

(空白のまま)

ヌル許可(オン)

適用外

3

Dept_Name

CHAR

20

ヌル不可(オフ)

大文字小文字を区別しない(オン)

なし

ファイル]>[保管]を選択して、テーブルに加えた変更を保存します。列の作成が完了すると、テーブルは次のようになります。

次に、テーブルのインデックスを追加しましょう。

  1. ウィンドウの下部にある[インデックス]タブをクリックします。
  2. 追加]ボタンをクリックします。
  3. インデックス名に Course_Code を選択して[OK]をクリックします。
  4. インデックス セグメントの詳細]で[一意]を選択します。
  5. のリストに ID があり、ソート順昇順であることを確認します。

完了すると、次のようになります。

ファイル]>[保管]を選択して、テーブルに加えた変更を保存します。

Zen Control Center を使用してテーブルの行を作成することもできますが、ここでは、JCL を使用してプログラムから行を操作することに焦点を当てます。

JCL を使用してテーブルに行を挿入する

作成した Course テーブルに新しい行を追加する簡単な Java プログラムを書きましょう。

コマンド プロンプトまたはターミナルを開いて、Java ソース ファイルを作成できるディレクトリに移動します。以下の手順では、C:\actian\jcl にコードを置きます。

テキスト エディターまたは Java 開発環境を使用して、JCLCreate.java というファイルを作成し、そのファイルに次のコードをコピーします。

import pervasive.database.*;

public class JCLCreate {

  public static void main(String[] args) {

    try {
      Session session = Driver.establishSession();

      // The database name is case-insensitive
      Database db = session.connectToDatabase("btrv:///zenjcldb");

      // Retrieve the Course table object,
      // the table name here is case-sensitive
      Table table = db.getTable("Course");

      RowSet rowset = table.createRowSet();

      // We’ll create a new row to insert into the table
      Row row = rowset.createRow();

      // Insert data into the row by setting each column value separately
      row.setString(0, "PHY203"); // we can specify the column by number
      row.setString("Description", "Thermodynamics"); // or by column name
      row.setInt("Credit", 5); // column names are case-sensitive
      row.setString(3, "Physics"); // column numbers are 0-based

      // Insert the Row object to the table
      rowset.insertRow(row);

      System.out.println("New course added.");
    } catch (PsqlException e) {
      e.printStackTrace();
    }
    System.out.println("Creation completed.");
  }
}

何をしているのかを理解するために、コードを順を追って説明しましょう。

  1. まず、JCL パッケージの pervasive.database をインポートします。
    import pervasive.database.*;
  2. 次に、データベースに接続できるよう、基本のドライバーへの接続を表す Driver クラスを使用してセッションを確立し、Session オブジェクトを取得します。
    Session session = Driver.establishSession();
  3. connectToDatabase() メソッドの引数として接続文字列 btrv:///zenjcldb を渡してデータベースに接続し、Database オブジェクトを取得します。
    Database db = session.connectToDatabase("btrv:///zenjcldb");
  4. getTable() メソッドを使用して、データベースから Course テーブル オブジェクトを取得します。
    Table table = db.getTable("Course");
  5. Table オブジェクトの createRowSet() を呼び出して RowSet を取得します。このメソッドは、ディスクに物理的に格納されるデータの表現(仮想テーブル)を作成します。
    RowSet rowset = table.createRowSet();

    RowSet オブジェクトは、テーブルの行を挿入、更新、および削除するためのメソッドを提供します。

  6. 新しい行を挿入するには、まず、RowSet オブジェクトの createRow() メソッドを呼び出して空の行を作成します。
    Row row = rowset.createRow();

    Row オブジェクトは、行内の列の値を取得または設定するメソッドを提供します。

  7. 行にデータを入力するには、Row オブジェクトの setDataType() メソッド(setInt()、setString() など)を使用して、各列の値を設定します。set メソッドの最初のパラメーターは列で、列番号(0 基準)または列名(大文字と小文字を区別)のいずれかで指定できます。2 番目のパラメーターはデータ自体です。ここでは、両方のメカニズムを使用します。
    // Insert data into the row by setting each column value separately
    row.setString(0, "PHY203"); // we can specify the column by number
    row.setString("Description", "Thermodynamics"); // or by column name
    row.setInt("Credit", 5); // column names are case-sensitive
    row.setString(3, "Physics"); // column numbers are 0-based
  8. この新しい行を Course テーブルに挿入するには、Row オブジェクトを指定して RowSet オブジェクトの insertRow() メソッドを呼び出します。
    rowset.insertRow(row);

次に、このコードをコンパイルして実行しましょう。

コンパイルします。

javac JCLCreate.java

次のように実行します。

java JCLCreate

すべてがうまくいけば、次のように表示されます。

New course added.
Creation completed.

何かがうまくいかなかった場合は、スタック トレースが表示されます。

新しい行が挿入されたことを確認するには、Zen Control Center を表示して、ツリー内の Course テーブルをダブルクリックします。新しいコースの行が次のように表示されます。

おめでとうございます。Java コードを使用して、Actian Zen データベースにデータを正常に挿入できました。

次のプログラム(JCLInsert.java というファイルに保存されています)により、このチュートリアルの残り部分で使用するデータをさらに挿入します。

import pervasive.database.*;

public class JCLInsert {

  public static void main(String[] args) {

    try {
      Session session = Driver.establishSession();

      Database db = session.connectToDatabase("btrv:///zenjcldb");

      Table table = db.getTable("Course");

      RowSet rowset = table.createRowSet();

      insertRow(rowset, "CSC101", "Intro to Computing", 5, "Computer Science");
      insertRow(rowset, "CSC102", "Intro to Programming", 3, "Computer Science");
      insertRow(rowset, "CSC203", "Prog Concepts I", 3, "Computer Science");
      insertRow(rowset, "CSC204", "Prog Concepts II", 3, "Computer Science");
      insertRow(rowset, "CSC305", "Prog Languages", 3, "Computer Science");
      insertRow(rowset, "MAT101", "College Algebra", 3, "Mathematics");
      insertRow(rowset, "MAT102", "Pre-Calculus", 3, "Mathematics");
      insertRow(rowset, "MAT203", "Calculus I", 4, "Mathematics");
      insertRow(rowset, "MAT204", "Calculus II", 4, "Mathematics");
      insertRow(rowset, "PHY102", "Physical Science", 3, "Physics");
      insertRow(rowset, "PHY204", "Physics II", 3, "Physics");
      insertRow(rowset, "PHY305", "Electromagnetism I", 3, "Physics");
      insertRow(rowset, "PHY306", "Electronics II", 3, "Physics");

      System.out.println("New courses added.");
    } catch (PsqlException e) {
      e.printStackTrace();
    }
  }

  private static void insertRow(
      RowSet rowset, String id, String description,
      int credit, String dept) throws PsqlException {

    Row row = rowset.createRow();

    row.setString("ID", id);
    row.setString("Description", description);
    row.setInt("Credit", credit);
    row.setString("Dept_Name", dept);

    rowset.insertRow(row);
  }
}

Java および JCL を使用したデータの読み取り

このセクションでは、Java クラス ライブリ(JCL)を使用して基本的なクエリを実行する方法を学習します。ここでは、標準の CRUD データベース操作の Read(読み取り)部分について説明します。

  • RowSet を使用して行を取得する
  • 行データを読み取る
  • すべての行を取得する
  • 行のサブセットを取得する
  • 行を取得するための完全な例
  • 反復する方向を変更する
  • インデックスを使用して特定の行を取得する

RowSet を使用して行を取得する

RowSet オブジェクトで提供される getNext() メソッドは、行セット内の行を反復処理し、各行を Row オブジェクトとして返します。各行セットのインスタンスは、内部の「カレンシー」(つまり「カーソル」)によって、反復のどこにいるかについて独自のレコードを保持しています。行セットが作成されるとき、カレンシーは最初の行の直前を指します。したがって、次の例では、行がある場合、取得される行はテーブル内の最初の行です。

try {
  // code to connect to the database and
  // get the table would go here

  RowSet rowset = table.createRowSet();
  // the currency now points to just before the first row

  // getNext gets the next row, which is the first one
  Row row = rowset.getNext();

  //
  // now we can read columns from this row
  //
} catch(PsqlEOFException ex) {
  // This exception is thrown if we’re past the last row
  System.out.println("End of table reached.");
} catch (PsqlException e) {
  // catch any other problems
  e.printStackTrace();
}

行がない場合、または行セットの最後にカレンシーがあった場合には、getNext() 呼び出しにより PsqlEOFException がスローされるので、それをキャッチする必要があります。

行データを読み取る

これで、行を取得できるようになりました。行にデータを書き込むために使用されるメソッドに類似したメソッドを使用して、行の内容を列ごとに読み取ることができます。

Row オブジェクトの getDataType() メソッドを使用します。列の整数値を取得する getInt()、文字列値を取得する getString() などがあります。これらのメソッドを呼び出すときは、列番号(0 基準)または列名(大文字と小文字を区別)のいずれかを指定します。

// Get column value by column number
String id = row.getString(0);
String description = row.getString(1);

// Can also get column value by column name
int credit = row.getInt("Credit");
String deptName = row.getString("Dept_Name");

すべての行を取得する

テーブル内のすべての行を取得するには、RowSet オブジェクトの getNext() メソッドをループの中で継続的に呼び出し、行セットの最後に達したことを知らせる PsqlEOFException がスローされるまで繰り返します。次のコードは、各レコードの内容を表示します。

try {

  // code to connect to the database and
  // get the table would go here

  RowSet rowset = table.createRowSet();
  // the currency points to just before the first row

  // now we can loop from the first row to the last
  while (true) {
    Row row = rowset.getNext();
    // get the Description column value and display it
    String description = row.getString("Description");
    System.out.println(description);
  }
} catch(PsqlEOFException e) {
  System.out.println("End of table reached.");
}

行のサブセットを取得する

テーブル内の行のサブセット、たとえば、数学科が提供するコースのみを取得するには、この行のサブセットを選択するための基準を提供する必要があります。

Dept_Name 列のデータが Mathematics と等しい行のサブセットが必要なので、その列を表すオブジェクトを取得する必要があります。このオブジェクトは、行セットのメタデータから取得します。

まず、メタデータを取得します。

RowSetMetaData rsmd = rowset.getRowSetMetaData();

次に、列の値を取得した場合と同様に、列名または 0 基準の番号を指定して ColumnDef オブジェクトを取得します。Dept_Name の ColumnDef を取得するには、次の処理を実行します。

ColumnDef columnDef = rsmd.getColumnDef(3);

名前を使用して ColumnDef を取得することもできます。

ColumnDef columnDef = rsmd.getColumnDef("Dept_Name");

次に、ColumnDef オブジェクト、比較演算子、フィルター式の値から成る条件を追加して、サブセットの基準を追加します。たとえば、次のように最初の条件を RowSetMetaData に追加します。

rsmd.addFirstTerm(columnDef, Consts.BTR_EQ, "Mathematics");

JCL には、次のようないくつかの比較演算子が用意されています。

  • BTR_EQ:等しい
  • BTR_NOT_EQ:等しくない
  • BTR_GR:より大きい
  • BTR_GR_OR_EQ:以上
  • BTR_LESS:より小さい
  • BTR_LESS_OR_EQ:以下

RowSetMetaData オブジェクトの addOrTerm() または addAndTerm() メソッドを呼び出すことで、最初の基準に基準を追加して、行のサブセットを絞り込むことができます。これらのメソッドも、ColumnDef オブジェクト、比較演算子、およびフィルター列の値を受け入れます。

たとえば、Dept_Name が Physics である行も考慮に入れるには、次のようにします。

rsmd.addOrTerm(columnDef, Consts.BTR_EQ, "Physics");

名前が示すように、addOrTerm() は論理関係の OR を示すのに対し、addAndTerm() は論理関係の AND を示します。前に定義した選択条件とこれらを組み合わせます。

これで、行セットを反復処理すると、Dept_Name が Physics または Mathematics である行のみを取得できます。

行を取得するための完全な例

すべてを 1 つの Java プログラムにまとめましょう。このプログラムでは、ZENJCLDB データベースの Course テーブルから数学科(Mathematics)または物理学科(Physics)が提供するコースの一覧に関する情報を取得します。

新しいファイル JCLRead.java を作成して以下のコードをコピーします。データベース(ZENJCLDB)に接続してテーブル(Course)を取得し、テーブルから RowSet オブジェクトを作成するコードについては、既に見てきました。

import pervasive.database.*;
public class JCLRead {
  public static void main(String[] args) {
    try {
      Session session = Driver.establishSession();
      Database db = session.connectToDatabase("btrv:///zenjcldb");
      Table table = db.getTable("Course");
      RowSet rowset = table.createRowSet();
      searchForMathOrPhysics(rowset);
      System.out.println("Courses by Mathematics or Physics departments");
      System.out.println("=============================================");
      displayRows(rowset);
    } catch (PsqlException e) {
      e.printStackTrace();
    }
  }

  public static void searchForMathOrPhysics(RowSet rowset) {
    // to be implemented
  }

  public static void displayRows(RowSet rowset) throws PsqlException {
    // to be implemented
  }
}

次に、searchForMathOrPhysics() メソッドを実装します。BTR_EQ 比較演算子を OR 条件と組み合わせて使用することにより、RowSet を、Dept_Name 列が Mathematics または Physics である行のみに制限します。

public static void searchForMathOrPhysics(RowSet rowset) {
    RowSetMetaData rsmd = rowset.getRowSetMetaData();
    ColumnDef deptNameColDef = rsmd.getColumnDef("Dept_Name");
    // Search for where the column equals Mathematics
    rsmd.addFirstTerm(deptNameColDef, Consts.BTR_EQ, "Mathematics");
    // Or the column equals Physics
    rsmd.addOrTerm(deptNameColDef, Consts.BTR_EQ, "Physics");
    // Set the row set’s current row (currency) to before the first row
    rowset.reset();
}

次に、現在の行セットのすべての行を表示するためのコードを実装します。現在は、上で指定した条件に一致する行のみを含むように制約されています。

public static void displayRows(RowSet rowset) throws PsqlException {
  try {
    while (true) {
      Row row = rowset.getNext();
      String name = row.getString(0);
      String desc = row.getString("Description");
      int credit = row.getInt(2);
      String deptName = row.getString("Dept_Name");
      System.out.println(name + " " + credit + " "
          + deptName + "\t" + desc);
    }
  } catch (PsqlEOFException e) {
    System.out.println("-------------");
    System.out.println("End of table.");
  }
}

完全なコードをコンパイルして JCLRead.java を実行すると、次のように出力されます。

Courses by Mathematics or Physics departments
=============================================
MAT101 3 Mathematics  College Algebra
MAT102 3 Mathematics  Pre-Calculus
MAT203 4 Mathematics  Calculus I
MAT204 4 Mathematics  Calculus II
PHY102 3 Physics Physical Science
PHY203 5 Physics Thermodynamics
PHY204 3 Physics Physics II
PHY305 3 Physics Electromagnetism I
PHY306 3 Physics Electronics II
-------------
End of table.

反復する方向を変更する

getNext() メソッドはデフォルトでは、行セット オブジェクトの順方向で次にある行を返します。RowSetMetaData オブジェクトの setDirection() メソッドを Const.BTR_BACKWARDS を引数として呼び出すことにより、逆方向で反復することができます。

RowSetMetaData rsmd = rowset.getRowSetMetaData();
rsmd.setDirection(Const.BTR_BACKWARDS);

順方向に切り替えるには、Const.BTR_FORWARDS を使用します。

rsmd.setDirection(Const.BTR_FORWARDS);

方向を RowSet の reset() メソッドと組み合わせると、最初の行または最後の行に移動することができます。

最初の行を取得するには、検索方向を前方(順方向)に設定し、reset() メソッドを使用して現在の行の位置を最初の行の前に設定してから、次(最初)の行を取得します。

rsmd.setDirection(Const.BTR_FORWARDS);
rowset.reset();
Row firstRow = rowset.getNext();

行セット内の最後の行を取得するには、検索方向を後方に設定し、行セットをリセット(reset())してから、getNext() を実行します。方向が後方であるため、リセットによって使用可能な行の最後に移動し、後方へ反復する準備ができます。

たとえば、次のコードにより、行セットの最後の行が取得されます。

rsmd.setDirection(Const.BTR_BACKWARDS);
rowset.reset();
Row lastRow = rowset.getNext();

インデックスを使用して特定の行を取得する

一意にインデックス付けされた列を比較演算子と共に使用すると、特定の行を取得することができます。たとえば、ID が PHY203 であるコース行を取得するには、ID 列を基に作成された一意のインデックス Course_Code を等しい比較演算子と共に使用します。

最初に、アクセス パスを目的のインデックスに設定します。インデックスは、0 基準の番号またはインデックスの名前のいずれかで指定します。次に、インデックス列を取得し、文字列を検索する値に設定します。最後に、RowSet の getByIndex() メソッドを使用して目的の行を取得します。

RowSetMetaData を使用してアクセス パスを設定します。

RowSetMetaData rsmd = rowset.getRowSetMetaData();
rsmd.setAccessPath("Course_Code");
// could also use the column index: rsmd.setAccessPath(0);

次に、Course_Code インデックスを表す Index オブジェクトを取得します。

Index index = rowset.createIndex("Course_Code");
// can also use the zero-based number: Index index = rowset.createIndex(0);

次に、Index オブジェクトで setString() メソッドを使用して、列の名前(インデックスの名前ではありません)と検索するデータを設定します。

index.setString("ID", "PHY203");
// can also use the column number: index.setString(0, "PHY203");

最後に、RowSet オブジェクトの getByIndex() メソッドを、比較演算子と Index オブジェクトを指定して呼び出し、目的の行(ID が PHY203 の行)を取得します。一致する行が見つからない場合は、PsqlOperationException がスローされるので注意してください。エラー コードは、見つからなかったことを示す 4 です。エラー コードが 4 でない場合は、何か他の問題が発生しています。

try {
  Row row = rowset.getByIndex(Consts.BTR_EQ, index);
  // now we have the matching row
} catch (PsqlOperationException e) {
  if (e.getErrorCode() == 4) {
    System.out.println("Matching row was not found");
  } else {
    throw(e);
  }
}

完全に機能するコード例は以下のとおりです。

import pervasive.database.*;
public class JCLReadByIndex {
  public static void main(String[] args) {
    try {
      Session session = Driver.establishSession();
      Database db = session.connectToDatabase("btrv:///zenjcldb");
      Table table = db.getTable("Course");
      RowSet rowset = table.createRowSet();
      RowSetMetaData rsmd = rowset.getRowSetMetaData();
      // set the access path to be through the index "Course_Code"
      rsmd.setAccessPath("Course_Code");
      // get the index object so we can set the ID to the
      // one we're looking for
      Index index = rowset.createIndex("Course_Code");
      index.setString("ID", "PHY203");
      System.out.println("Courses with Course Code of PHY203");
      System.out.println("==================================");
      // look for the matching row
      try {
        Row row = rowset.getByIndex(Consts.BTR_EQ, index);
        // now we have the matching row, so display it
        // otherwise if we didn't find it, an exception will be thrown
        String name = row.getString(0);
        String desc = row.getString("Description");
        int credit = row.getInt(2);
        String deptName = row.getString("Dept_Name");
        System.out.println(name + " " + credit + " "
            + deptName + "\t " + desc);
      } catch (PsqlOperationException e) {
        if (e.getErrorCode() == 4) {
          System.out.println("Matching row was not found");
        } else {
          throw(e);
        }
      }
    } catch (PsqlException e) {
      e.printStackTrace();
    }
  }
}

このコードを実行すると、次のように表示されます。

Courses with Course Code of PHY203
==================================
PHY203 5 Physics  Thermodynamics

存在しない ID(たとえば、"ACC201")を探すように上記のコードを変更した場合は、次のように表示されます。

Courses with Course Code of ACC201
==================================
Matching row was not found

Java および JCL を使用したデータの更新

このセクションでは、Java クラス ライブリ(JCL)を使用して CRUD データベース操作の Update(更新)部分を実行する方法を学習します。

  • 行を変更する
  • 特定の行を変更する
  • 行を更新するプログラムを書く

JCL は、データベースやテーブルの構造を変更する操作をサポートしていません。そのため、Zen Control Center を使用する必要があります。Zen Control Center を使用してテーブルの行を変更することもできますが、ここでは、JCL を使用して変更を加えることだけを見ていきます。

行を変更する

行のセットを変更するには、変更する行のセットを取得し、前に行を作成するときに使用されたメソッドと同様の setDataType() メソッドを使用し、行セットの updateRow() メソッドを使用して終わります。この例では、数学科(Mathematics)が提供するコースの行を変更します。

前述の「行のサブセットを取得する」トピックの手順に従って、目的の行を含む RowSet オブジェクトを作成することから始めます。

その後、行を反復処理して、行を取り出すごとに、次のように Credit 列の値を 5 に設定して更新します。

row.setInt("Credit", 5);

次に、updateRow() を渡して、更新された行を保存するよう RowSet に指示します。

rowset.updateRow(row);

行のサブセットを変更するためのコード スニペットの全体を以下に示します。

try {
  while (true) {
    // code to get subset of rows into rowset
    Row row = rowset.getNext();
    row.setInt("Credit", 5);
    rowset.updateRow(row);
  }
} catch (PsqlEOFException e) {
  System.out.println("End of update.");
}

特定の行を変更する

ID が PHY203 のコースの履修単位を 5 から 3 に変更するという、物理学科からの要求に応えて特定の行を変更するには、「インデックスを使用して特定の行を取得する」の説明に従ってその特定の行を取得してから、上記と同様の方法で行を変更します。

try {
  Row row = rowset.getByIndex(Consts.BTR_EQ, index);
  row.setInt("Credit", 3);
  rowset.updateRow(row);
} catch (PsqlOperationException e) {
  if (e.getErrorCode() == 4) {
    System.out.println("Matching row not found.");
  } else {
    throw(e);
  }
}

行を更新するプログラムを書く

特定の行を更新するための完全なコードは以下のとおりです。このプログラムを JCLUpdate.java として保存できます。

import pervasive.database.*;

public class JCLUpdate {

  public static void main(String[] args) {
    try {
      Session session = Driver.establishSession();
      Database db = session.connectToDatabase("btrv:///zenjcldb");
      Table table = db.getTable("Course");
      RowSet rowset = table.createRowSet();
      Row row = rowForPhysics203(rowset);
      if (row != null) {
        // Update column data
        row.setInt("Credit", 3);
        rowset.updateRow(row);
        System.out.println("Row updated.");
      }
    } catch (PsqlException e) {
      e.printStackTrace();
    }
  }

  private static Row rowForPhysics203(RowSet rowset) throws PsqlException {
    try {
      RowSetMetaData rsmd = rowset.getRowSetMetaData();
      // Set the access path to access rows by an index
      rsmd.setAccessPath("Course_Code");
      Index index = rowset.createIndex("Course_Code");
      // Pass the column and our search value
      index.setString("ID", "PHY203");

      // Return a Row object that meets the criterion
      return rowset.getByIndex(Consts.BTR_EQ, index);
    } catch (PsqlOperationException e) {
      if (e.getErrorCode() == 4) {
        System.out.println("Row not found!");
        return null;
      } else {
        throw(e);
      }
    }
  }
}

JCLUpdate.java をコンパイルして実行します。

行が正常に変更されていることを確認するには、Zen Control Center でデータを見るか、または JCLRead.java プログラムを実行して、PHY203 コースの Credit が 3(以前は 5 でした)になっていることに注目します。

JCLUpdate.java の後に JCLRead.java を実行した結果の出力は、次のようになります。太字になっている変更された行に注目してください。

Courses by Mathematics or Physics departments
=============================================
MAT101 3 Mathematics     College Algebra
MAT102 3 Mathematics     Pre-Calculus
MAT203 4 Mathematics     Calculus I
MAT204 4 Mathematics     Calculus II
PHY102 3 Physics             Physical Science
PHY203 3 Physics          Thermodynamics
PHY204 3 Physics             Physics II
PHY305 3 Physics             Electromagnetism I
PHY306 3 Physics             Electronics II
-------------
End of table.

Actian Zen データベースの特定の行を変更するための Java プログラムが正常に作成されました。

Java および JCL を使用したデータの削除

このセクションでは、Java クラス ライブリ(JCL)を使用して CRUD データベース操作の Delete(削除)部分を実行する方法を学習します。

  • 行のセットを削除する
  • 特定の行を削除する
  • 行を削除するプログラムを書く
  • テーブルとデータベースを削除する

行のセットを削除する

行のセットを削除するには、「行のサブセットを取得する」と同じメカニズムを使用します。その後、行を反復処理するときに、getNext() メソッドを使用して各行を取り出し、その Row オブジェクトを引数として使用して、行セットで deleteRow() を呼び出します。

try {
  while(true) {
    // get subset of rows into rowset
    Row row = rowset.getNext();
    rowset.deleteRow(row);
  }
} catch (PsqlEOFException e) {
  System.out.println("End of deletion.");
}

特定の行を削除する

特定の行を削除するには、インデックスを使用して特定の行を取得するトピックのコードを使用して特定の行を取得することから始め、上記のように deleteRow() メソッドを使用します。次のセクションで、これを実行するための完全なプログラムを書きます。

行を削除するプログラムを書く

行の削除方法がわかったので、ID が PHY203 であるコースを削除する Java プログラムを書きましょう。このプログラムを JCLDelete.java として保存します。

import pervasive.database.*;

public class JCLDelete {
  public static void main(String[] args) {
    try {
      Session session = Driver.establishSession();
      Database db = session.connectToDatabase("btrv:///zenjcldb");
      Table table = db.getTable("Course");
      RowSet rowset = table.createRowSet();

      // Get the RowSet object’s RowSetMetaData
      RowSetMetaData rsmd = rowset.getRowSetMetaData();

      // Set the access path to access rows by index name
      rsmd.setAccessPath("Course_Code");

      // Get an Index object representing the Course_Code index
      Index index = rowset.createIndex("Course_Code");

      // Set the column name and the value to find
      index.setString("ID", "PHY203");

      // create and configure index
      Row row = rowset.getByIndex(Consts.BTR_EQ, index);
      rowset.deleteRow(row);
    } catch (PsqlOperationException e) {
      if (e.getErrorCode() == 4) {
        System.out.println("Matching row not found.");
      } else {
        e.printStackTrace();
      }
    } catch (PsqlException e) {
      e.printStackTrace();
    }
  }
}

JCLDelete.java をターミナルでコンパイルして実行し、行が正常に削除されたかどうかを Zen Control Center で調べるか、または JCLRead プログラムを実行して確認します。

テーブルとデータベースを削除する

JCL は、プログラムによるテーブルおよびデータベースの削除をサポートしていません。このタスクは、Zen Control Center を使用して実行します。詳細については、Zen Control Center ドキュメントを参照してください。