マスター/ディテール・ビューについて

ビュー・リンクは、アプリケーション・モジュール内のビュー・オブジェクトの動作に影響を与えます。ビュー・オブジェクトがマスター/ディテール・ビュー・リンクのディテール側として使用されている場合、そのビュー・オブジェクトでは、ビュー・リンクを定義しているAssociationにより指定された制限ビューが選択されます。制限の意味は、マスターの現在の行に関連する行のみが、ディテール・ビュー・オブジェクトのデータとして表示されるということです。

ビュー・オブジェクトがマスター/ディテール・ビュー・リンクの一部でない場合、ビュー・オブジェクトはデータの無制限ビューを表示します。つまり、データのすべての行が使用可能になります。たとえば、次の図は、DEPT表のDeptViewおよびEMP表のEmpViewという2つのビューがプロジェクトで提供される場合を表しています。アプリケーションの目的上、MyDeptViewMyEmpDetailViewおよびMyEmpViewというビューの別名を定義するとします。MyDeptViewMyEmpDetailViewをマスター/ディテール関係でリンクします。この場合、MyEmpDetailViewにある従業員データは、MyDeptViewの現在の値に依存します。たとえば、現在の部門番号に関連付けられた従業員名のみが表示されます。

MyEmpViewでは、ビューに制限はなく、EMP表のすべてのデータを表示できます。DeptViewおよびEmpViewはビュー定義です。

Figure that shows an application module using a master-detail view and an    unrestricted view, as described in the preceding paragraphs.

次の図は、制限なしで動作し、EMP表の各行から指定の列をフェッチするMyEmpViewを示しています。

Figure that shows data from an unrestricted view, as described in the preceding paragraph.

これに対し、MyEmpDetailViewはビュー・リンクのディテール側です。その結果セットは、ビュー・リンクの属性により定義されている1つ以上のバインド値によって制限されます。このため、指定されたバインド値を含む行のみがフェッチされます。実際は、ビュー・リンクによって、ビュー・オブジェクトを定義しているSQL文にWHERE句が追加されます。たとえば、次の図は、DeptViewToEmpViewリンクで使用されているMyEmpDetailViewを示しています。ここで、(MyDeptViewdeptno属性により定義されている)バインド値は20であるため、MyEmpDetailViewは、deptnoが20である行のみをフェッチします。バインド値は、マスター・ビューにより提供されます。

Figure that shows data from a master-detail (restricted) view, as described in the preceding paragraph.

要約すると、ビュー・リンク内のディテール・ビュー・オブジェクトは、マスター・ビューにより提供されたバインド値に基づき、対象となるデータの制限ビューを選択します。無制限ビューを選択するには、アプリケーション・モジュール内に個別のビュー・オブジェクトを定義します。次のコード例では、制限ビューおよび無制限ビューの動作の違いと、ディテール・ビューがバインド値によりマスター・ビューにどのように依存するかを示しています。

package d2e;
import oracle.jbo.*;
public class AliasDemo {
public static void main(String[] args) {
    // Helper routine connects to the generic application module.
ApplicationModule appMod =
QueryDemo.getGenericAppMod(JboContext.PLATFORM_LOCAL);
    // Call method to get UnrestrictedView.
ViewObject voEmp = appMod.findViewObject("MyEmpView");
printRows(voEmp); // Prints all rows in EMP.
    // Assume MyDeptView and EmpView were linked
// master-detail at design time.
voEmp = appMod.findViewObject("EmpView"); // Restricted view.
printRows(voEmp); // No master view yet, so no rows printed.
    ViewObject voMaster = appMod.findViewObject("MyDeptView");
voMaster.first(); // Get bind values from first row of master table.
printRows(voEmp); // Prints restricted view.
}
  public static void printRows(ViewObject vo) {
System.out.println("ViewObject :"+vo.getName()+" - RowCount:"+vo.getRowCount() );
    // Execute the query, print results to the screen.
vo.executeQuery();
while (vo.hasNext()) {
Row row = vo.next();
String rowDataStr = "";
      // How many attributes (columns) is the view object using?
int numAttrs = vo.getAttributeCount();
      // Column numbers start with 0, not 1.
for (int attrNo = 0; attrNo < numAttrs; attrNo++) {
        // See also Row.getAttribute(String name).
Object attrData = row.getAttribute(attrNo);
rowDataStr += (attrData + "\t");
}
System.out.println(rowDataStr);
}
}
}

ビュー・リンクおよびイベントについて

2つのビュー・オブジェクトがマスター/ディテール関係でリンクされている場合、マスター・ビュー・オブジェクトのデフォルトのイテレータにより、イベントが起動され、ディテール・ビュー・オブジェクトがリフレッシュされます。ディテール・ビュー・オブジェクトが作成される際、Business Components for Javaフレームワークにより、マスターのイテレータのイベント・リスナーとして登録されます。このため、次の図に示すように、イテレータがマスター・ビュー・オブジェクト内の別の行に移動すると、ディテール・ビュー・オブジェクトの内容は自動的にリフレッシュされます。

図1: 

Figure that shows how changes in a master view's iterator causes a refresh of    detail view's contents, as described in the preceding paragraph.

次のコード例では、アプリケーション・モジュールが少なくとも1つのビュー・リンクを含むように、設計時に定義されていることを前提にしています。このコードでは、アプリケーション・モジュールが初期化され、最初のリンクが取得され、リンクからマスターおよびディテールのビュー・オブジェクトが取得されて、各マスター行とリンク先のディテール行が表示されます。

package d2e;
import oracle.jbo.*;
public class LinkDemo {
public static void main(String[] args) {
    // Helper routine connects to the generic application module.
ApplicationModule appMod = QueryDemo.getGenericAppMod(JboContext.PLATFORM_LOCAL);
    // Get the first link defined in the application module.
String[] linkNames = appMod.getViewLinkNames();
if (linkNames.length < 1) {
System.out.println("\n No links.");
return;
}
    ViewLink link = appMod.findViewLink(linkNames[0]);
    // Get view objects defined in the link.
ViewObject voMaster = link.getSource();
ViewObject voDetail = link.getDestination();
    // Execute query and move through the master rows.
voMaster.executeQuery();
while (voMaster.hasNext()) {
printRow(voMaster.next());
      // JDeveloper automatically refreshes the detail result set.
// Move through linked detail rows.
while (voDetail.hasNext()) {
printRow(voDetail.next());
}
}
}
  // This is a helper method that prints data to the screen.
public static void printRow(Row row) {
String rowAttrs = "";
for (int i = 0; i < row.getAttributeCount(); i++) {
rowAttrs += (row.getAttribute(i) + "\t");
}
System.out.println(rowAttrs);
}
}

次の図は、マスター・ビュー・オブジェクトとディテール・ビュー・オブジェクト間のイベント・フローを示しています。リンクを定義すると、Business Components for Javaフレームワークはディテール・ビュー・オブジェクトを登録し、対応するマスター・ビュー・オブジェクトからのイベントをリスニングできるようにします。マスター・ビュー・オブジェクト内の現在の行が変更されると、フレームワークはイベントを起動し、ディテール・ビュー・オブジェクトは、ディテール・ビュー・オブジェクトをリフレッシュして応答します。次にこのアクションにより別のイベントが起動され、登録されたリスナーがあれば、そのリスナーによりそのイベントが処理されます。

Figure that shows the event flow between master and detail view objects, as described in the preceding paragraphs.