EJB Data Mediator Service für Datenzugriff verwenden

Die folgenden Schritte beschreiben anhand von Codebeispielen das Erstellen der Metadaten für den EJB Data Mediator Service (DMS).

Vorgehensweise

  1. Eine Mediatorinstanz wird mit einer der folgenden create-Methoden der Mediator-Factory (com.ibm.websphere.sdo.mediator.ejb.MediatorFactory) erstellt. Beispiel:
    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. Es sind drei Varianten der Methode createMediator verfügbar. Die Argumente sind im Folgenden erläutert:
    createMediator( query, parms) 
    createMediator( query, parms, schema )
    createMediator( query, parms, schema,  typeMap,  pattern)
    Tabelle 1. Argumente für die Methode "createMediator". Die Argumente sind in der folgenden Tabelle definiert:
    Typ Argument Beschreibung
    String query Array von EJB-Abfrageanweisungen
    Object parms Werte für Eingabeparameter für die Abfrageanweisungen
    Eclass* schema Die EClass des Stammdatenobjekts
    Map* typeMap java.util.Map, die EJB Abstract Schema Names aus der Abfrageanweisung in Eclass-Namen umsetzt
    int* pattern Das für den Einschluss (Containment) zu verwendende Muster
     
    * wird nur verwendet, wenn ein vom Aufrufenden angegebenes Schema verwendet wird.

Beispiel

Abfrageargumente mit EJB-Mediator verwenden

Die folgenden Beispiele veranschaulichen, wie Sie die Abfrageargumente für Enterprise JavaBeans (EJB) Mediator optimieren können.

Einfaches Beispiel
Diese Abfrage gibt einen DataGraph mit mehreren Instanzen von DataObjects des Typs (Eclass-Name) Emp zurück. Die Datenobjektattribute sind empid und name. Die Datentypen dieser Attribute entsprechen den CMP-Feldtypen.
select  e.empid, e.name
from Emp as e
where e.salary > 100
Der zurückgegebene und im XML-Format serialisierte DataGraph sieht wie folgt aus:
<?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>
Abfrageparameter
Dieses Beispiel demonstriert die Verwendung von Parametermarken. Wie Sie sich erinnern werden, haben Parametermarken in einer EJB-Abfrage die Syntax ?n (Fragezeichen, gefolgt von einer Zahl). Wenn Sie die Methode getGraph ( ) für den EJBMediator aufrufen, können Sie optional ein Array mit Werten übergeben. ?n bezieht sich auf den Wert von parm[n-1]. Das Array mit Werten kann auf mit dem Factoryaufruf zum Erstellen des EJBMediator übergeben werden. Mit getGraph( ) übergebene Parameter setzen die mit dem Aufruf von create übergebenen Parameter außer Kraft.
select  e.empid, e.name
from Emp as e
where e.salary > ?1 
Rückgabe von Ausdrücken und Methoden
Dieses Beispiel zeigt, dass die Datenobjektattribute Rückgabewerte von Abfrageausdrücken sein können. Zu den EJB-Abfrageausdrücken gehören arithmetische Ausdrücke, Date-Time-Ausdrücke, Pfadausdrücke und Methoden. Eingabeargumente und Rückgabewerte von Methoden sind auf die Liste der unterstützten Datentypen beschränkt. Lesen Sie hierzu den Artikel "Abfragesyntax für EJB Mediator". Ein Datenobjekt, das ein aus einem Ausdruck abgeleitetes aktualisiertes Attribut enthält, führt während der Verarbeitung von applyChanges zu einer Ausnahme, wenn der Benutzer keinen MediatorAdapter für die Handhabung der Änderung angegeben hat.
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
Die Namen von Datenobjektattributen werden aus den CMP-Feldnamen abgeleitet, können jedoch mit dem Schlüsselwort AS in der Abfrage überschrieben werden. Wenn Sie einen Ausdruck angeben, sollten Sie immer das Schlüsselwort AS verwenden, um dem Ausdruck einen Namen zu geben.
Syntax mit *
Die Schreibweise e.* ist eine Kurzform für die Angabe aller CMP-Felder (jedoch nicht der containergesteuerten Beziehungen) einer EJB. Die folgende Abfrage hat dieselbe Bedeutung wie e.empid, e.name e.salary, e.bonus.
select e.* from Emp as e
Kein Primärschlüssel in SELECT-Klausel
Dieses Beispiel zeigt eine Abfrage, die nicht das Primärschlüsselfeld zurückgibt. Solange das Datenobjekt nicht alle Primärschlüsselfelder für eine EJB enthält, kann der Mediator jedoch keine Updates für den DataGraph verarbeiten. Dies liegt daran, dass der Primärschlüssel für die Umsetzung der Änderungen in SQL oder die Konvertierung von DataObject-Referenzen in EJB-Referenzen erforderlich ist. Wenn versucht wird, applyChanges auszuführen, tritt eine Ausnahme ein.
select e.name, e.salary from Emp as e
'ORDER BY'-Klausel
DataObjects können sortiert werden.
select d.* from Dept d  order by d.name
	select e.* from in(d.emps) e order by e.empid desc
Dies bewirkt eine Sortierung der Dept-Objekte nach Namen und der Emp-Objekte innerhalb jedes Dept-Objekts nach empid in absteigender Reihenfolge.
Navigation in einer Beziehung mit mehreren Werten
Diese Verbundabfrage gibt einen DataGraph mit den DataObject-Klassen Dept und Emp zurück. Die Form des DataGraph spiegelt die in den FROM-Klauseln verwendeten Pfadausdrücke wider.
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 ist in diesem Fall der Stammknoten im DataGraph. Wie nachfolgend gezeigt gibt es von Dept auf Emp eine Referenz mit mehreren Werten:
<?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>
Weitere Informationen zu Abfrageparametern
Für jede Abfrage können Suchbedingungen angegeben werden. Die Eingabeparameter sind globale Parameter für die Abfrage und können an beliebiger Stelle der Verbundabfrage nach Nummer referenziert werden. Im obigen Beispiel sollten die im Aufruf von create oder getGraph übergebenen Abfrageargumente die Reihenfolge { deptno-Wert, salary-Wert, deptno-Wert } haben.
select d.* from Dept as d
   where d.deptno between ?1 and ?3
select e.* from in(d.emps) e
   where e.salary < ?2
Navigation auf einem Pfad mit mehreren Beziehungen
Die folgende Abfrage navigiert auf dem Pfad, der sich aus den EJB-Beziehungen Dept.projs und Project.tasks zusammensetzt und DataObjects für Dept, Emp und Project zurück, die ausgewählte CMP-Felder enthalten.
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
Das resultierende Datendiagramm im XML-Format sehen Sie hier:
<?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>
Navigation auf mehreren Pfaden
Nachfolgend sehen Sie eine Mediator-Abfrage, die einen DataGraph mit DataObjects für Dept mit den zugehörigen employees zurückgibt, und einen zweiten Pfad, der die zugehörigen Projekte und Tasks abruft.
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
Der zurückgegebene DataGraph sieht wie folgt aus:
<?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>
Navigation in einer Beziehung mit einem Wert
Hier ist als besonders wichtig anzumerken, dass obwohl Emp das Stammdatenobjekt im Diagramm ist, einem Dept-Datenobjekt mehrere Emp-Datenobjekte zugeordnet sind. Im Gegensatz zu den vorherigen Beispielen hat das Datendiagramm nicht die Form einer Baumstruktur, wenn Sie sich die Datenobjektinstanzen ansehen. Es gibt mehrere Stamm-Emp-Objekte, die einem Dept-Objekt zugeordnet sind. Es handelt sich hier um ein Datendiagramm und nicht um einen Datenstrukturbaum. Beachten Sie, dass in der FROM-Klausel von Mediator-Abfragen Pfadausdrücke mit nur einem Wert zulässig sind. Dies ist eine Abweichung von der Standard-EJB-Abfragesyntax.
select e.empid, e.name  from Emp e
select d.deptno, d.name  from in(e.dept) d
Der DataGraph im XML-Format sieht wie folgt aus:
<?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>
Pfadausdrücke in der SELECT-Klausel
Diese Abfrage ähnelt der vorherigen (beide Abfragen geben Mitarbeiterdaten mit Abteilungsnummer und Namen zurück). Das Datendiagramm enthält in dieser Abfrage jedoch nur einen Datenobjekttyp (und nicht zwei wie in der vorherigen Abfrage). Die deptno-Felder und das Namensfeld sind schreibgeschützt, weil sie das Ergebnis eines Pfadausdrucks in der SELECT-Klausel und keine CMP-Felder der Emp-EJB sind.
select  e.empid as EmplId , e.name as EmpName ,
		 		 e.dept.deptno as DeptNo , e.dept.name as DeptName
from Emp as e
Navigation in einer N:M-Beziehung
Die Emp-Task-Beziehung ist eine N:M-Beziehung. Die folgende Abfrage ruft Mitarbeiter (employees), Tasks und Projekte ab. Es gibt jeweils nur ein Vorkommen eines bestimmten Task-DataObject im DataGraph, selbst wenn dieses mehreren Mitarbeitern zugeordnet sein kann.
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
Mehrere Verbindungen zwischen Datenobjekten
Mit dem EJB Mediator können Sie Daten basierend auf Beziehungen abrufen und den Befehl XREL verwenden, um eine oder mehrere zusätzliche Beziehungen basierend auf den bereits abgerufenden Daten erstellen. Außerdem unterstützt der Mediator das Abrufen von Daten basierend auf dem ASNname und die anschließende Erstellung einer oder mehrerer Beziehungen basierend auf den mit dem Befehl XREL abgerufenden Daten. Die folgende Abfrage ruft Abteilungen (departments), Mitarbeiter (employees), die in den Abteilungen arbeiten, und Mitarbeiter ab, die die Abteilungen verwalten.
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
Die zweite und dritte select-Klausel geben beide Instanzen des DataObject Emp zurück. Es ist möglich, dass durch die Beziehung d.emps und die die Beziehung d.manager dieselbe Emp-Instanz abgerufen wird. Der EJB-Mediator erstellt eine Emp-Instanz, erstellt aber beide Beziehungen.
Die folgende Abfrage wird wie folgt verarbeitet. DataObjects vom Typ Dept werden aus den Daten in der ersten Abfrage erstellt. DataObjects vom Typ Emp werden aus den Daten in der zweiten Abfrage erstellt. Anschließend werden für alle Beziehungen, die in der FROM-Klausel oder in einem XREL-Schlüsselwort verwndet werden, Beziehungen im Graphen erstellt. Während der Erstellung der Beziehungen werden keine weiteren Daten abgerufen. In diesem Beispiel erscheint ein Mitarbeiter, der in der Abteilung Dev arbeitet, im DataGraph. Wenn dieser Mitarbeiter eine Abteilung mit dem Namen Sales verwaltet, ist die Referenz manages leer. In der ersten Abfrage wurde die Abteilung Dev und nicht die Abteilung Sales abgerufen.
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
Die Beziehung zwischen emps und manager wird basierend auf den von den Abfragen erstellten DataObject-Instanzen gebildet. Ein Mitarbeiter mit dem Namen "Dev", der in der Abteilung "Sales" arbeitet, hat im Graphen keine Beziehung zu dept.
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
Das nächste Beispiel zeigt den Abfruf von Datenobjekten für alle Mitarbeiter, Projekte und Tasks für eine bestimmte Abteilung und die Verknüpfung von Mitarbeitern mit Tasks.
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

Wenn eine Task einem Mitarbeiter in Abteilung 42 zugeordnet ist, erscheint diese Verknüpfung im Datengraph. Wenn die Task einem Mitarbeiter in einer anderen Abteilung als 42 zugeordnet ist, erscheint diese Verknüpfung nicht im Datengraphen, weil das Datenobjekt von der Abfrage gefiltert wurde. Einem XREL-Schlüsselwort können eine oder mehrere EJB-Beziehungen folgen. Bidirektionale Beziehungen können auf jeden Rollennamen verweisen. Quelle und Ziel der Beziehung müssen mit einer oder mehreren Abfragen abgerufen werden.

Nicht zusammengehörige Objekte abrufen
Die folgende Abfrage ruft Dept und Task ab.
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'
Die folgende Abfrage ruft Dept und Emps ab. Obwohl es Beziehungen zwischen Dept und Emp (mgr und emps) gibt, wird keine Beziehung in FROM oder XREL verwendet. Deshalb enthält der erstellte Graph auch keine Beziehungswerte.
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%'
Nicht vorhandene oder leere Beziehungen abrufen
Diese Abfrage gibt Abteilungen zurück, die keine Mitarbeiter haben, oder Mitarbeiter ohne Abteilung zurück. Es ist anzunehmen, dass die Anwendung die Mitarbeiter einer der Abteilungen zuordnen möchte. Mit XREL wird die Beziehung e.dept (und die umgekehrte Beziehung d.emps) im Graphenschema definiert.
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
Collection-Eingabeparameter
Eine Gruppe von Enterprise-Beans kann als Eingabeargument an den EJB Mediator übergeben und in der FROM-Klausel referenziert werden. Mit der Verwendung eines Collection-Parameters wird die Anforderung erfüllt, ein Datendiagramm aus einer benutzerdefinierten Gruppe bereits aktivierter Enterprise-Beans zu konstruieren.
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
Die angegebene Abfrage geht die Gruppe der Dept-Beans und zugehörigen Emp-Beans durch, wendet die Abfrageprädikate an und konstruiert das Datendiagramm. Es werden die aktuellen Werte der Beans verwendet. Beispiel für ein Programm mit einem EJB-Collection-Parameter:
// Diese Methode wird in einem EJB-Kontext innerhalb des Geltungsbereichs einer Transaktion ausgeführt.
public DataGraph meineServicemethode() {
      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); // Erhöhung um 10 % für alle
      }

      // Erstellen des Collection-Parameters der Abfrage
      Collection c = new LinkedList();
      c.add(dept);
      Object[] parms = new Object[] { c};  // EJB-Gruppe wird in Parameter-Array gestellt

      // Die Gruppe mit der dept-EJB wird an den EJB Mediator übergeben.

      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;
      // Der DataGraph enthält die aktualisierten und noch nicht übergebenen
      // Gehaltsinformationen. Die Dept- und Emp-Daten werden über EJB-
      // Instanzen, die im EJBContainer aktiv sind, abgerufen.
      // Projektdaten werden mittels containergesteuerter Beziehungen
      // aus der Datenbank abgerufen.
   }
MediatorAdapter verwenden

In diesem Beispiel verarbeitet der Adapter CREATE-Ereignisse für ein EMP-Datenobjekt. Die Attribute "name" und "salary" werden aus dem Datenobjekt extrahiert und an die Methode create von EmpLocalHome übergeben.

Die Methode create gibt eine Instanz der Emp-EJB zurück, und der Primärschlüsselwert wird zurück in das Datenobjekt kopiert. Der Aufrufende kann dann den generierten Schlüsselwert abrufen. Nach Abschluss der Verarbeitung gibt der Adapter den Wert true zurück. Alle anderen Änderungen werden vom Adapter ignoriert und vom EJB-Mediator verarbeitet.

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;

// Beispiel für eine Adapterklasse, die eine EJB-Methode create aufruft

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() ); // Primärschlüssel in SDO setzen
				return true;	
      			} catch(Exception e){ // Code für Fehlerbehandlung
      }
		}
		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) { // Code für Fehlerbehandlung
      }
  }

  	public void end(){}
}

Symbol, das den Typ des Artikels anzeigt. Taskartikel



Symbol für Zeitmarke Letzte Aktualisierung: 25.05.2016
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tejb_ejbmeduse
Dateiname:tejb_ejbmeduse.html