ネストされた表の反復使用
表を反復して使用する場合、または複数の取得操作を実行している場合、デフォルトでは操作中の表から行のみが取得されます。ただし、MultiRowOptions
を使用すると、その親表および子表も取得するように指定できます。
これを実行する場合、まず親表が取得され、操作中の表が取得された後、子表が取得されます。つまり、表の階層的順序が順守されます。
取得される親表および子表を指定するには、クラス・コンストラクタでTable
オブジェクトのList
をancestors
およびchildren
パラメータに指定します。MultiRowOptions.setIncludedChildTables()
またはMultiRowOptions.setIncludedParentTables()
メソッドを使用して指定することもできます。
複数の表から取得された行を操作する場合、その行が属する表を決定するのはユーザーです。
たとえば、次のような子および孫表を含む表を作成するとします。
CREATE TABLE prodTable (
prodType STRING,
typeDescription STRING,
PRIMARY KEY (prodType)
)
CREATE TABLE prodTable.prodCategory (
categoryName STRING,
categoryDescription STRING,
PRIMARY KEY (categoryName)
)
CREATE TABLE prodTable.prodCategory.item (
itemSKU STRING,
itemDescription STRING,
itemPrice FLOAT,
vendorUID STRING,
inventoryCount INTEGER,
PRIMARY KEY (itemSKU)
)
次のようなデータを含む表:
-
行1:
-
prodType: Hardware
-
typeDescription: Equipment、toolsおよびparts
-
行1.1:
-
categoryName: Bolts
-
categoryDescription: Metric & US Sizes
-
行1.1.1:
-
itemSKU: 1392610
-
itemDescription: 1/4-20 x 1/2 Grade 8 Hex
-
itemPrice: 11.99
-
vendorUID: A8LN99
-
inventoryCount: 1457
-
-
-
-
行2:
-
prodType: Tools
-
typeDescription: Handおよびpower tools
-
行2.1:
-
categoryName: Handtools
-
categoryDescription: Hammers、screwdrivers、saws
-
行2.1.1:
-
itemSKU: 1582178
-
itemDescription: Acme 20 ounce claw hammer
-
itemPrice: 24.98
-
vendorUID: D6BQ27
-
inventoryCount: 249
-
-
-
この場合、次のように、この表に含まれるすべてのデータを表示できます。
まず、すべての表ハンドルを取得します。
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);
try {
while (iter.hasNext()) {
Row row = iter.next();
displayRow(row);
}
} finally {
if (iter != null) {
iter.close();
}
}
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);
try {
while (iter.hasNext()) {
Row row = iter.next();
displayRow(row);
}
} finally {
if (iter != null) {
iter.close();
}
}