データ・アクセスでの EJB データ・メディエーター・サービスの使用

次のステップではコード・サンプルを使用して、Enterprise JavaBeans (EJB) データ・メディエーター・サービス (DMS) メタデータを作成する方法について簡単な例を説明します。

手順

  1. メディエーター・インスタンスは、以下の例のように、メディエーター・ファクトリー (com.ibm.websphere.sdo.mediator.ejb.MediatorFactory) で create メソッドの 1 つを使用して作成されます。
    import com.ibm.websphere.sdo.mediator.ejb.Mediator;
    import com.ibm.websphere.sdo.mediator.ejb.MediatorFactory;
    import com.ibm.webpshere.ejbquery.QueryException;
    import commonj.sdo.DataObject;
    
    try{
     String[] query =  { "select d.deptno,d.name from DeptBean as d" }; 
     Mediator m = MediatorFactory.getInstance().createMediator( query, null);
     DataObject root = m.getGraph();
    } catch (QueryException e) { ... } 
  2. createMediator メソッドには、3 つの異なる形式があります。引数の説明を次に示します。
    createMediator( query, parms) 
    createMediator( query, parms, schema )
    createMediator( query, parms, schema,  typeMap,  pattern)
    表 1. createMediator メソッドの引数. 引数について、以下の表で説明します。
    タイプ 引数 説明
    ストリング query EJB 照会ステートメントの配列
    オブジェクト parms 照会ステートメントの入力パラメーターの値
    Eclass* スキーマ (schema) ルート DataObject の EClass
    Map* typeMap Eclass 名に照会ステートメントからの EJB 抽象スキーマ名をマップする java.util.Map
    int* pattern 収容のために使用されるパターン
     
    * は、スキーマを提供された呼び出し元を使用する場合にのみ使用されます

EJB メディエーターでの照会引数の使用

Enterprise JavaBeans (EJB) メディエーター照会引数を微調整する方法を次の例に示します。

簡単な例
この照会は、タイプ (Eclass name) Emp の DataObjects の複数インスタンスを含む DataGraph を戻します。 データ・オブジェクト属性は、empid および name で、 データ型はコンテナー管理パーシスタンス (CMP) フィールド・タイプに対応しています。
select  e.empid, e.name 
from Emp as e
where e.salary > 100
XML フォーマット内でシリアライズされて戻された DataGraph は 、以下のようになります。
<?xml version="1.0" encoding="ASCII"?>
<datagraph:DataGraphSchema xmlns:datagraph="datagraph.ecore">
<root>
<Emp empid="1003" name="Eric" />
<Emp empid="1004" name="Dave" />
</root>
</datagraph:DataGraphSchema>
照会パラメーター
以下の例は、パラメーター・マー カーの使用方法を示しています。 EJB 照会内のパラメーター・マーカーの構文は、数値が後に続く疑問符 (?n) であることを思い出してください。 EJBMediator 上で getGraph( ) メソッドを呼び出すときは、オプションで 値の配列を受け渡すことができます。 ?n は、parm[n-1] の値を参照しています。 値の配列はまた、ファクトリー呼び出し上 で受け渡されて、EJBMediator を作成することができます。 getGraph( ) 上で受け渡されたパラメーターは、作成呼び出し上で受け渡 されたあらゆるパラメーターをオーバーライドします。
select  e.empid, e.name 
from Emp as e
where e.salary > ?1 
戻り式およびメソッド
以下の例は、データ・オブジェ クト属性は照会式の戻り値である可能性があることを示しています。 EJB 照会式は、演算、日時、パス式、およびメソッドを含んでいます。 入力引数およびメソッドからの戻り値は、サポート・データ型のリストに制限されています。トピック『EJB メディエーター照会構文』を参照してください。 式から派生した更新属性を含むデータ・オブジェクトは、変更を取り扱 う MediatorAdapter をユーザーが提供しない限りは、applyChanges の処理中 、例外を発生させます。
select  e.empid as employeeId, 
  e.bonus+e.salary as totalPay,  
  e.dept.mgr.name as managerNam, 
  e.computePension( ) as pension 
from Emp as e
where e.salary > 100
データ・オブジェクトの属性名は CMP フィールド名から派 生していますが、照会内の AS キーワードを使用してオーバーライドすることができます。 式を指定するとき、式に名前を与えるために常時 AS キーワードが使用されます。
* 構文
表記 e.* は EJB のための すべての CMP フィールド (ただし、コンテナー管理関係を除く) を指定する ためのショートカットです。 次の照会は、e.empid, e.name e.salary, e.bonus と同じ意味になります。
select e.* from Emp as e
SELECT 文節内に 1 次キーなし
以下の例は、1 次キー・フ ィールドを戻さない照会を表示しています。 しかし、データ・オブジェクトが EJB のためのすべての 1 次キー・フィー ルドを含んでいない限りは、DataGraph への更新はメディエーターによっては処理できません。 これは 1 次キーが、Structured Query Language (SQL) への変更を翻訳するか、または DataObject 参照を EJB 参照へ変換することを要求されているからです。 applyChanges を実行しようとするときの例外
select e.name, e.salary from Emp as e
順序
DataObjects は配列することができます。
select d.* from Dept d  order by d.name
	select e.* from in(d.emps) e order by e.empid desc
これによって、Dept オブジェクトは名前で配列され、 Emp オブジェクトはそれぞれの Dept 内で empid によって降順に配列されます。
多値関係のナビゲート
この複合照会は、DataObject クラス Dept および Emp で DataGraph を戻します。 DataGraph の形状は、FROM 文節で使用されるパス式を反映します。
select d.deptno, d.name, d.budget from Dept d  
						where d.deptno < 10 
select e.empid, e.name, e.salary  from in(d.emps) e 
						where e.salary > 10
この場合、Dept は DataGraph 内のルート・ノードで、以下に示すように Dept から Emp への多値参照があります。
<?xml version="1.0" encoding="ASCII" ?> 
<datagraph:DataGraphSchema xmlns:datagraph="datagraph.ecore">
<root>
<Dept deptno="1" name="WAS_Sales" budget="500.0" 
   emps="//@root/@Emp.1 //@root/@Emp.0" /> 
<Dept deptno="2" name="WBI_Sales" budget="450.0" 
   emps="//@root/@Emp.3 //@root/@Emp.2" /> 
<Emp empid="1001" name="Rob" salary="100.0" EmpDept="//@root/@Dept.0" /> 
<Emp empid="1002" name="Jason" salary="100.0" EmpDept="//@root/@Dept.0" /> 
<Emp empid="1003" name="Eric" salary="200.0" EmpDept="//@root/@Dept.1" /> 
<Emp empid="1004" name="Dave" salary="500.0" EmpDept="//@root/@Dept.1" /> 
</root>
</datagraph:DataGraphSchema>
照会パラメーターの詳細
検索条件はどの照会上でも指定できます。 入力引数は照会に対してグローバルで、複合照会内の任意の位置で数値によって参照されます。 前の例では、create または getGraph 呼び出し上で受け渡された照会引数は、{ deptno value, salary value, deptno value } の配列でなければなりません。 .
select d.* from Dept as d 
   where d.deptno between ?1 and ?3 
select e.* from in(d.emps) e  
   where e.salary < ?2
複数関連でのパスのナビゲート
次の照会は、 EJB 関係 Dept.projs および Project.tasks から構成されるパスをナビゲートし、 選択された CMP フィールドを含む Dept、Emp および Project 用の DataObjects を戻します。
select d.deptno, d.name from Dept as d 
select p.projid from in(d.projects) p 
select t.taskid, t.cost from  in (p.tasks) t
XML フォーマットの結果のデータ・グラフを以下に表示します。
<?xml version="1.0" encoding="ASCII" ?> 
<datagraph:DataGraphSchema xmlns:datagraph="datagraph.ecore">
<root>
<Dept deptno="1" name="WAS_Sales" projects="//@root/@Project.0" /> 
<Dept deptno="2" name="WBI_Sales" projects="//@root/@Project.1" /> 
<Project projid="1" ProjectDept="//@root/@Dept.0" 
      tasks="//@root/@Task.0   //@root/@Task.2 //@root/@Task.1" /> 
<Project projid="2" ProjectDept="//@root/@Dept.1" 
      tasks="//@root/@Task.3" /> 
<Task taskid="1" cost="50.0" TaskProject="//@root/@Project.0" /> 
<Task taskid="2" cost="60.0" TaskProject="//@root/@Project.0" /> 
<Task taskid="3" cost="900.0" TaskProject="//@root/@Project.0" /> 
<Task taskid="7" cost="20.0" TaskProject="//@root/@Project.1" /> 
</root>
</datagraph:DataGraphSchema>
複数のパスのナビゲート
以下に、従業員に関連した Dept の DataObjects を持つ DataGraph および関連したプロジェクトおよびタスクを検索する 2 番目のパスを戻すメディエーター照会があります。
select d.deptno, d.name from Dept d 
select e.empid, e.name  from in(d.emps) e
select p.projid from in(d.projects) p 
select t.taskid, t.cost from in(p.tasks) where t.cost > 10
戻された DataGraph は、以下のようになりえます。
<?xml version="1.0" encoding="ASCII" ?> 
    <datagraph:DataGraphSchema xmlns:datagraph="datagraph.ecore">
    <root>
        <Dept deptno="1" name="WAS_Sales" projects="//@root/@Project.0"     
            emps="//@root/@Emp.1 //@root/@Emp.0" /> 
        <Dept deptno="2" name="WBI_Sales" projects="//@root/@Project.1" 
            emps="//@root/@Emp.3 //@root/@Emp.2" /> 
        <Project projid="1" ProjectDept = "//@root/@Dept.0"
            tasks="//@root/@Task.0   //@root/@Task.2 //@root/@Task.1" /> 
        <Project projid="2" ProjectDept="//@root/@Dept.1" 
            tasks="//@root/@Task.3" /> 
        <Task taskid="1" cost="50.0" TaskProject="//@root/@Project.0" /> 
        <Task taskid="2" cost="60.0" TaskProject="//@root/@Project.0" /> 
        <Task taskid="3" cost="900.0" TaskProject="//@root/@Project.0" /> 
        <Task taskid="7" cost="20.0" TaskProject="//@root/@Project.1" /> 
        <Emp empid="1001" name="Rob" EmpDept="//@root/@Dept.0" /> 
        <Emp empid="1002" name="Jason" EmpDept="//@root/@Dept.0" /> 
        <Emp empid="1003" name="Eric" EmpDept="//@root/@Dept.1" /> 
        <Emp empid="1004" name="Dave" EmpDept="//@root/@Dept.1" /> 
  </root>
  </datagraph:DataGraphSchema>
単一値関係のナビゲート
ここで指摘するべき大切なこ とは、たとえ Emp がグラフ内のルート・データ・オブジェクトであっても、 複数の Emp データ・オブジェクトが同じ Dept データ・オブジェクトと関連があるということです。 したがって、前の例とは異なり、データ・オブジェクト・インスタンスを調べても、データ・グラフはツリー状になっていません。同じ Dept オブジェクトに関連するルート Emp オブジェクトが複数あります。しかし、結局はデータ・グラフであってデータ・ツリーではありません。 メディエーター照会によって単一値パス式が FROM 文節で許可されることに注 意してください。 これは、標準 EJB 照会構文からの変更です。
select e.empid, e.name  from Emp e 
select d.deptno, d.name  from in(e.dept) d 
XML フォーマットの DataGraph は以下のようになります。
<?xml version="1.0" encoding="ASCII" ?> 
   <datagraph:DataGraphSchema xmlns:datagraph="datagraph.ecore">
   <root>
      	<Emp empid="1001" name="Rob" dept="//@root/@Dept.0" /> 
      	<Emp empid="1002" name="Jason" dept="//@root/@Dept.0" /> 
      	<Emp empid="1003" name="Eric" dept="//@root/@Dept.1" /> 
      	<Emp empid="1004" name="Dave" dept="//@root/@Dept.1" /> 
      <Dept deptno="1" name="WAS_Sales" DeptEmp="//@root/@Emp.1 //@root/@Emp.0" /> 
      <Dept deptno="2" name="WBI_Sales" DeptEmp="//@root/@Emp.3 //@root/@Emp.2" /> 
   </root>
   </datagraph:DataGraphSchema>
SELECT 文節内のパス式
この照会は、前のものと類 似しています (照会は両方とも部門番号および名前とともに従業員データを 戻し返します)。しかし、データ・グラフがこの照会内でデータ・オブジェク ト・タイプを 1 つしか含まないことに注意してください (一方、前の照会で は 2 つです)。 フィールドの部門番号および名前フィールドは読み取り専用です。SELECT 文節内のパス式の結果であり、 Emp EJB の CMP フィールドではないからです。
select  e.empid as EmplId , e.name as EmpName ,
		 		 e.dept.deptno as DeptNo , e.dept.name as DeptName
from Emp as e
many: many 関係のナビゲート
Emp から Task への関係は、many:many 関係と見なされます。 次の照会は従業員、タスク、およびプロジェクトを検索します。 任意の特定タスク DataObject は、多くの従業員と関連している可能性がありますが、 DataGraph 内には 1 つしか出現しません。
select e.empid, e.name from Emp as e
select t.taskid, t.description from in(e.tasks) as t
select p.projid, p.cost from in(t.proj) as p
データ・オブジェクト間の複数のリンク
EJB メディエーターを使用すると、関係に基づいてデータを検索でき、XREL コマンドを使用して、既に検索したデータに基づいて 1 つ以上の追加の関係を作成することができます。 メディエーターはさらに、ASNname に基づいたデータの検索も使用可能にし、XREL コマンドを使用して、検索したデータに基づき 1 つ以上の関係を作成できます。 次の照会は部門、その部門で働く従業員、およびその部門を管理する従業員を検索します。
select d.deptno, d.name from Dept d where d.name like ‘%Dev%'
select e.empid, e.name from in (d.emps) as e
select m.empid, m.name from in(d.manager) as m
2 番目および 3 番目の select 文節は、いずれも Emp DataObject のインスタンスを戻します。 d.emps 関係および d.manager 関係から同じ Emp インスタンスが検索される可能性もあります。 EJB メディエーターは 1 つの Emp インスタンスを作成しますが、両方の関係を作成します。
次の照会は以下のように処理されます。 最初の照会でデータから Dept DataObjects が作成されます。 2 回目の照会でデータから Emp DataObjects が作成されます。 次に、FROM 文節または XREL キーワードのいずれかで使用されるすべての関係について、グラフ内に関係が作成されます。 関係の作成中には、追加のデータは検索されません。 次の例では、Dev という部門で働く従業員が DataGraph に表示されます。この従業員が Sales という部門を管理している場合、manages 参照は空です。 Sales 部門ではなく、Dev 部門が最初の照会で検索されました。
select d.deptno, d.name from Dept d where d.name like ‘%Dev%'
select e.empid, e.name from in (d.emps) as e xrel d.manager
従業員とマネージャーの関係は、照会から作成される DataObject インスタンスに基づいて作成されます。 「Dev」という名前の従業員が「Sales」部門で働いている場合、グラフ内で「null」の部門関係を持ちます。
select d.deptno, d.name from Dept d where d.name like ‘%Dev%'
select e.empid, e.name from Emp e where e.name like ‘Dev%' xrel d.emps, d.manager
次の例は、指定部門のすべての従業員、プロジェクト、およびタスクのデータ・オブジェクトの検索と、従業員とタスクとのリンケージを示しています。
select d.deptno from Dept d where d.deptno = 42
select e.empid from in(d.emps) e
select p.projid from in(d.projs) p
select t.* from in(p.tasks) t xrel e.tasks

部門 42 の従業員にタスクが割り当てられると、そのリンクがデータ・グラフに表示されます。 部門 42 に属さない従業員にタスクが割り当てられると、そのデータ・オブジェクトは照会によって フィルタリングされて除外されるため、そのリンクはデータ・グラフには表示されません。 1 つの XREL キーワードの後に、1 つ以上の EJB 関係を続けることができます。 双方向関係は、いずれのロール名も参照することができます。 関係のソースおよびターゲットの両方とも、1 つ以上の照会によって検索される必要があります。

無関連オブジェクトの検索
次の照会は部門およびタスクを検索します。
select d.deptno, d.name from Dept d where d.name like ‘%Dev%'
select t.taskid, t.startDate from Task t where t.startDate > ‘2005'
次の照会は部門および従業員を検索します。部門と従業員 (すなわち mgr および emp) の間に関係があったとしても、いずれの関係も FROM や XREL では使用されず、結果としてグラフには関係値が含まれません。
select d.deptno, d.name from Dept d where d.name like ‘%Dev%'
select e.empid, e.name from Emp e where e.dept.name like ‘%Dev%'
ヌルまたは空の関係の検索
この照会は、従業員を持たない部門および部門を持たない従業員を戻します。 アプリケーションは、従業員を部門の 1 つに割り当てようとすることが推定されます。 xrel の目的は、e.dept 関係 (および逆のロールである d.emps 関係) をグラフ・スキーマに定義することです。
select d.deptno, d.name from Dept d where d.emps is empty
select e.empid, e.name from Emp e where e.dept is null xrel e.dept
コレクション入力パラメーター
エンタープライズ Bean のコレクションは、入力引数としてメディエーターに渡し、FROM 文節内で参照できます。 コレクション・パラメーターを使用すると、既にアクティブにされたエンタープライズ Bean のユーザー・コレクションからデータ・グラフを構成する要件が満たされます。
select d.deptno, d.name from ((Dept) ?1) as d
select e.empid, e.name from in(d.emps) as e where e.salary > 10
指定された照会は、Dept Bean および関連した Emp Bean のコレクションで繰り返され、照会述部を適用してデータ・グラフを構成します。 値は、Bean の現行値から取得されます。 EJB コレクション・パラメーターを使用するパラメーターの例。
// this method runs in an EJB context and within a transaction scope   
public DataGraph myServiceMethod() { 
      InitialContext ic = new InitialContext();
      DeptLocalHome deptHome = ic.lookup("java:comp/env/ejb/Dept");
      Integer deptKey = new Integer(10);
      DeptEJB dept = deptHome.findByPrimaryKey( deptKey));
      Iterator i = dept.getEmps().iterator();
      while (i.hasNext()) {
        EmpEJB e = (EmpEJB)i.next();
        e.setSalary( e.getSalary() * 1.10); // give everyone a 10% raise 
      }

      // create the query collection parameter
      Collection c = new LinkedList();
      c.add(dept);
      Object[] parms = new Object[] { c};  // put ejb collection in parm array.

      // collection containing the dept EJB is passed to EJB Mediator

      String[] query = new String[] 
      { "select d.deptno, d.name from ((Dept)?1 ) as d",
          "select e.empid, e.name, e.salary " +
          " from in (d.employees) as e", 
          "select p.projno, p.name from in (d.projects) as p" };

      Mediator m = EJBMediatorFactory.getInstance().createMediator(query, parms);
      DataGraph dg = m.getGraph();
      return dg;
      // the DataGraph contains the updated and as yet uncommitted 
      //  salary information.  Dept and Emp data is fetched through
      // EJB instances active in the EJBContainer. 
      //  Project data is retrieved from database using 
      //   container managed relationships.  
   }
MediatorAdapter の使用

この例では、アダプターが EMP データ・オブジェクトの CREATE イベントを処理します。 名前およびサラリー属性は、データ・オブジェクトから抽出されて、EmpLocalHome 上の create メソッドへ受け渡されます。

create メソッドは Emp EJB のインスタンスを戻し、1 次キー値はコピーされて DataObject へ戻されます。 次に呼び出し元は、生成されたキー値を取得することができます。 処理後、アダプターは true のを戻します。 他のすべての変更は、アダプターによって無視され、EJB Mediator によって処理されます。

package com.example;
import com.ibm.websphere.sdo.mediator.ejb.*;
import javax.naming.InitialContext;
import commonj.sdo.ChangeSummary;
import commonj.sdo.DataObject;
import commonj.sdo.DataGraph;
import commonj.sdo.ChangeSummary;

// example of Adapter class calling a EJB create method.

public class SalaryAdapter implements MediatorAdapter{

  	ChangeSummary log = null;
  EmpLocalHome empHome = null;

  	public boolean applyChange(DataObject object,  int phase){

				if (object.getType().getName().equals("Emp")
		     		     && phase == MediatorAdapter.CREATE){
			try{
								String name = object.getString("name");
								double salary = object.getDouble("salary");
								EmpLocal emp = empHome.create(name, salary);
								object.set("empid", emp.getPrimaryKey() ); // set primary key in SDO
				return true;	
      			} catch(Exception e){ // error handling code goes here 
      }
		}
		return true;
  }

  	public void init (ChangeSummary log){ 
      try {
        		this.log = log;
        InitialContext ic = new InitialContext();
        		empHome = (EmpLocalHome)ic.lookup(	"java:comp/env/ejb/Emp");
      } catch (Exception e) { // error handling code goes here
      }
  }

  	public void end(){}
}

トピックのタイプを示すアイコン タスク・トピック



タイム・スタンプ・アイコン 最終更新: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tejb_ejbmeduse
ファイル名:tejb_ejbmeduse.html