MultiRowOptionsを使用したネスト表の取得

表を反復して使用する場合、または複数の取得操作を実行している場合、デフォルトでは操作中の表から行のみが取得されます。ただし、MultiRowOptionsを使用すると、その親表および子表も取得するように指定できます。

これを実行する場合、まず親表が取得され、操作中の表が取得された後、子表が取得されます。つまり、表の階層的順序が順守されます。

取得される親表および子表を指定するには、クラス・コンストラクタでTableオブジェクトのListancestorsおよびchildrenパラメータに指定します。MultiRowOptions.setIncludedChildTables()またはMultiRowOptions.setIncludedParentTables()メソッドを使用して指定することもできます。

複数の表から取得された行を操作する場合、その行が属する表を決定するのはユーザーです。

たとえば、次のような子および孫表を含む表を作成するとします。

table create -name prodTable
add-field -type STRING -name prodType
add-field -type STRING -name typeDescription
primary-key -field prodType
exit
plan add-table -name prodTable -wait

table create -name prodTable.prodCategory
add-field -type STRING -name categoryName
add-field -type STRING -name categoryDescription
primary-key -field categoryName
exit
plan add-table -name prodTable.prodCategory -wait

table create -name prodTable.prodCategory.item
add-field -type STRING -name itemSKU
add-field -type STRING -name itemDescription
add-field -type FLOAT -name itemPrice
add-field -type STRING -name vendorUID
add-field -type INTEGER -name inventoryCount
primary-key -field itemSKU
exit
plan add-table -name prodTable.prodCategory.item -wait

次のようなデータを含む表:

この場合、次のように、この表に含まれるすべてのデータを表示できます。

まず、すべての表ハンドルを取得します。

package kvstore.tableExample;

import java.util.Arrays;

import oracle.kv.KVStore;
import oracle.kv.KVStoreConfig;
import oracle.kv.KVStoreFactory;

import oracle.kv.table.PrimaryKey;
import oracle.kv.table.Row;
import oracle.kv.table.Table;
import oracle.kv.table.TableAPI;

import oracle.kv.table.TableIterator;
import oracle.kv.table.MultiRowOptions;

...

private static Table prodTable;
private static Table categoryTable;
private static Table itemTable;

private static TableAPI tableH;

...

// KVStore handle creation is omitted for brevity

...

tableH = kvstore.getTableAPI();
prodTable = tableH.getTable("prodTable");
categoryTable = tableH.getTable("prodTable.prodCategory");
itemTable = tableH.getTable("prodTable.prodCategory.item"); 

ここで、上位レベル表を反復する場合に使用するPrimaryKeyおよびMultiRowOptionsが必要です。上位レベル表のすべての行が必要なため、空のPrimaryKeyを作成します。

MultiRowOptionsは、コンストラクタのchildパラメータに含まれる2つの子表を指定します。これにより、上位レベル表のすべての行およびネストされた子表のすべての行が反復して返されます。

// Construct a primary key
PrimaryKey key = prodTable.createPrimaryKey();

// Get a MultiRowOptions and tell it to look at both the child
// tables
MultiRowOptions mro = new MultiRowOptions(null, null,
        Arrays.asList(categoryTable, itemTable));

ここで、反復を実行します。

// Get the table iterator
// Exception handling is omitted, but in production code
// ConsistencyException, RequestTimeException, and FaultException
// would have to be handled.
TableIterator<Row> iter = tableH.tableIterator(key, mro, null);
while (iter.hasNext()) {
    Row row = iter.next();
    displayRow(row);
} 

displayRow()メソッドは、行が属する表を決定し、その行を適切な方法で表示するために使用されます。

private static void displayRow(Row row) {
    // Display the row depending on which table it belongs to
    if (row.getTable().equals(prodTable)) {
        displayProdTableRow(row);
    } else if (row.getTable().equals(categoryTable)) {
        displayCategoryTableRow(row);
    } else {
        displayItemTableRow(row);
    }
} 

最後に、各行を表示するために使用するメソッドが必要です。これらのメソッドは簡単ですが、HTMLページの作成や、レポートのPDFコピーを生成するためのXSL-FOの作成などの複雑な処理を実行するために、より高度なアプリケーションで使用される可能性があります。

private static void displayProdTableRow(Row row) {
    System.out.println("\nType: " + 
        row.get("prodType").asString().get());
    System.out.println("Description: " + 
        row.get("typeDescription").asString().get());
}

private static void displayCategoryTableRow(Row row) {
    System.out.println("\tCategory: " + 
        row.get("categoryName").asString().get());
    System.out.println("\tDescription: " + 
        row.get("categoryDescription").asString().get());
}

private static void displayItemTableRow(Row row) {
    System.out.println("\t\tSKU: " + 
        row.get("itemSKU").asString().get());
    System.out.println("\t\tDescription: " + 
        row.get("itemDescription").asString().get());
    System.out.println("\t\tPrice: " + 
        row.get("itemPrice").asFloat().get());
    System.out.println("\t\tVendorUID: " + 
        row.get("vendorUID").asString().get());
    System.out.println("\t\tInventory count: " + 
        row.get("inventoryCount").asInteger().get());
    System.out.println("\n");
} 

最下位の子で取得する場合でも、取得順序は最上位の先祖から最下位の子の順のままであることに注意してください。たとえば、次のように、すべてのボルトおよびそのすべての親表を取得できます。

// Get all the table handles
prodTable = tableH.getTable("prodTable");
categoryTable = tableH.getTable("prodTable.prodCategory");
itemTable = tableH.getTable("prodTable.prodCategory.item");

// Construct a primary key
PrimaryKey key = itemTable.createPrimaryKey();
key.put("prodType", "Hardware");
key.put("categoryName", "Bolts");

// Get a MultiRowOptions and tell it to look at both the ancestor
// tables
MultiRowOptions mro = new MultiRowOptions(null,
        Arrays.asList(prodTable, categoryTable), null);

// Get the table iterator
// Exception handling is omitted, but in production code
// ConsistencyException, RequestTimeException, and FaultException
// would have to be handled.
TableIterator<Row> iter = tableH.tableIterator(key, mro, null);
while (iter.hasNext()) {
    Row row = iter.next();
    displayRow(row);
}