Utilisation du service DMS (Data Mediator Service) EJB pour l'accès aux données

Les étapes suivantes utilisent des exemples de codes pour décrire une instance simple de création de métadonnées de service DMS EJB.

Procédure

  1. Une instance de médiateur est créée à l'aide des méthodes create de la fabrique de médiateurs (com.ibm.websphere.sdo.mediator.ejb.MediatorFactory) comme dans l'exemple suivant :
    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. Il existe trois formes différentes de méthode createMediator. Les arguments sont explicités comme suit :
    createMediator( query, parms) 
    createMediator( query, parms, schema )
    createMediator( query, parms, schema,  typeMap,  pattern)
    Tableau 1. arguments de méthode createMediator. Les arguments sont décrits dans le tableau suivant :
    Type Argument Description
    String (chaîne) query tableau d'instructions de requête EJB
    Objet parms valeurs des paramètres d'entrée des instructions de requête
    Eclass* schéma EClass de l'objet de données racine
    Map* typeMap mappe java.util.Map qui met en correspondance des noms de schéma abstraits (noms ASN, Abstract Schema) d'EJB de l'instruction de requête avec des noms Eclass
    int* pattern type de confinement utilisé
     
    * utilisé uniquement avec le schéma de fournisseur d'appelants

Exemple

Utilisation d'arguments de requête avec le médiateur EJB.

Les exemples suivants vous indiquent comment définir les arguments de requête de votre médiateur Enterprise JavaBeans (EJB).

Exemple simple
Cette requête renvoie un datagraphe contenant plusieurs instances d'objet de données de type (nom Eclass) Emp. Les attributs de l'objet de données sont empid et name et leurs types de données correspondent aux types de zones CMP.
select  e.empid, e.name 
from Emp as e 
where e.salary > 100
Le datagraphe renvoyé sérialisé au format XML se présente ainsi :
<?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>
Paramètres de requête
Cet exemple montre comment utiliser des marqueurs de paramètre. Rappelez-vous que dans une requête d'EJB les marqueurs de paramètre sont symbolisés par un point d'interrogation suivi d'un chiffre (?n). Lors de l'appel de la méthode getGraph ( ) sur le médiateur d'EJB, vous pouvez éventuellement transmettre un tableau de valeurs. ?n fait référence à la valeur de parm[n-1]. Le tableau de valeurs peut également être transmis sur l'appel de fabrique de connexions pour créer le médiateur d'EJB. Les paramètres transmis avec getGraph( ) remplacent tous les paramètres transmis avec l'appel create.
select  e.empid, e.name 
from Emp as e 
where e.salary > ?1 
Retour d'expressions et de méthodes
Cet exemple montre que les attributs d'objet de données peuvent être les valeurs renvoyées par les expressions de requête. Les expressions de requête d'EJB sont notamment des expressions arithmétiques, de date et heure, de chemins, et des méthodes. Les arguments d'entrée et les valeurs de retour de ces méthodes sont strictement limités à la liste des types de données pris en charge (voir Syntaxe de la requête du médiateur d'EJB). Lorsqu'un objet de données contenant un attribut mis à jour est dérivé d'une expression, une exception se produit lors du processus applyChanges à moins que l'utilisateur fournisse un adaptateur de médiateur pour gérer la modification.
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
Les noms d'attribut d'objet de données sont dérivés des noms de zone CMP mais peuvent être remplacés en insérant le mot clé AS dans la requête. Lors de la spécification d'une expression, le mot clé AS doit toujours être utilisé pour attribuer un nom à l'expression.
Syntaxe *
La notation e.* est un raccourci permettant de désigner toutes les zones CMP (mais pas les relations gérées par conteneurs) d'un EJB. La requête suivante a la même signification que e.empid, e.name e.salary, e.bonus.
select e.* from Emp as e
Pas de clé primaire dans la clause select
Cet exemple présente une requête qui ne renvoie pas la zone de clé primaire. Toutefois, à moins que l'objet de données ne contienne toutes les zones de clé primaire d'un EJB, le médiateur ne peut pas traiter les mises à jour du datagraphe. En effet, la clé primaire est nécessaire pour convertir les modifications en SQL ou pour convertir les références d'objet de données en références EJB. Une exception se produit lors de la tentative d'exécution de applyChanges.
select e.name, e.salary from Emp as e
ORDER BY
Les objets de données peuvent être triés.
select d.* from Dept d  order by d.name
select e.* from in(d.emps) e order by e.empid desc
Cette opération entraîne le tri des objets Dept par noms et le tri des objets Emp contenus dans chaque Dept par ordre décroissant de empid.
Parcours d'une relation à plusieurs valeurs
Cette requête composée renvoie un datagraphe et les classes d'objet de données Dept et Emp. La forme du datagraphe reflète les expressions des chemin d'accès utilisées dans les clauses 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
Dans ce cas, Dept est le noeud racine du datagraphe et il existe une référence à plusieurs valeurs de Dept à Emp comme illustré :
<?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>
Informations supplémentaires sur les paramètres de requête
Des conditions de recherche peuvent être spécifiées dans toute requête. Les arguments d'entrée valent pour toute la requête et peuvent être référencés d'après un numéro dans n'importe quelle requête composée. Dans l'exemple précédent, les arguments de requête transmis par l'appel create ou getGraph doivent se présenter dans l'ordre { 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
Parcours d'un chemin avec relation à plusieurs valeurs
La requête suivante parcourt le chemin composé des relations entre les EJB Dept.projs et Project.tasks et renvoie pour Dept, Emp et Project des objets de données contenant les zones CMP sélectionnées.
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
Le datagraphe résultant au format XML est présenté ci-dessous.
<?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>
Parcours de plusieurs chemins
Voici une requête de médiateur qui renvoie un datagraphe des objets de données pour Dept avec les employés associés et un second chemin qui extrait les projets et tâches associés.
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
Le datagraphe renvoyé se présente ainsi :
<?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>
Parcours d'une relation à une seule valeur
L'élément important à noter ici est que même si Emp est l'objet de données racine du graphe, plusieurs objets de données Emp seront associés au même objet de données Dept. Donc, à la différence des exemples précédents, le datagraphe n'a pas la forme d'une arborescence lorsque vous visualisez les instances d'objet de données ; il existe plusieurs objets de données racine Emp associés au même objet de données Dept. Mais, après tout, il s'agit d'un datagraphe et non d'une arborescence de données. Les requêtes du médiateur acceptent les expressions de chemin à valeur unique dans la clause FROM. C'est une nouveauté dans la syntaxe des requêtes standard d'EJB.
select e.empid, e.name  from Emp e 
select d.deptno, d.name  from in(e.dept) d 
Le datagraphe au format XML se présente ainsi :
<?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>
Expressions de chemin dans la clause SELECT
Cette requête est similaire à la précédente (elle renvoie des données relatives aux employés ainsi que le nom et le numéro du département), mais le datagraphe ne contient qu'un seul type d'objet de données (alors qu'il en contenait deux dans la précédente). Les zones deptno et name sont en lecture seule car elles résultent d'une expression de chemin de la clause SELECT et ne sont pas des zones CMP de l'EJB Emp.
select  e.empid as EmplId , e.name as EmpName ,
		 e.dept.deptno as DeptNo , e.dept.name as DeptName
from Emp as e
Parcours d'une relation many:many
La relation Emp à Task est considérée comme une relation many:many. La requête suivante extrait les employés, tâches et projets. Il n'existe qu'une seule occurrence d'un objet de données de tâche spécifique dans le datagraphe, même s'il peut être associé à plusieurs employés.
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
Plusieurs liens entre les objets de données
Le médiateur EJB vous permet d'extraire les données en fonction des relations et d'utiliser la commande XREL pour construire une ou plusieurs relations supplémentaires sur la base des données déjà extraites. Le médiateur permet aussi l'extraction des données en fonction du ASNname puis la construction d'une ou plusieurs relations sur la base des données extraites à l'aide de la commande XREL. La requête suivante extrait les services, les employés des différents services ainsi que les employés qui gèrent chaque service.
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
Les deuxième et troisième clauses select renvoient des instances de l'objet de données Emp. Il est possible que la même instance Emp soit extraite dans la relation d.emps et la relation d.manager. Le médiateur EJB crée une seule instance Emp mais crée les deux relations.
La requête suivante est traitée comme suit. Les objets de données Dept sont créés à partir des données de la première requête. Les objets de données Emp sont créés à partir des données de la seconde requête. Dans le graphique, les relations sont alors construites pour toute relation utilisée dans la clause FROM ou un mot clé XREL. Lors de la construction de la relation, aucune donnée supplémentaire n'est extraite. Dans cet exemple, un employé qui travaille dans un service appelé Dev apparaît dans le datagaphe. Si cet employé gère un service appelé Sales, la référence manages est vide. Le service Dev a été extrait dans la première requête, et non le service Sales.
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
Les relations emps et manager sont construites en fonction des instances d'objet de données créées à partir des requêtes. Un employé dont le nom est "Dev" mais qui travaille dans le service "Sales" aura une relation de service nulle dans le graphique.
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
L'exemple suivant présente l'extraction des objets de données pour tous les employés, projets et tâches pour un service donné, ainsi que la liaison des employés aux tâches.
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

Si une tâche est assignée à un employé du service 42, alors ce lien s'affiche dans le datagraphe. Si la tâche est assignée à un employé qui ne fait pas partie du service 42, alors cette liaison n'apparaît pas dans le datagraphe car l'objet de données a été éliminé (filtrage) par la requête. Un mot clé XREL peut être suivi d'une ou plusieurs relations EJB. Les relations bidirectionnelles peuvent se référer à n'importe quel nom de rôle. La source et la cible de la relation peuvent être extraites par une ou plusieurs requêtes.

Extraction des objets non associés
La requête suivante extrait Dept et Task.
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'
La requête suivante extrait Dept et Emps. Même s'il existe une relation entre Dept et Emp (à savoir mgr et emps), aucune relation n'est utilisée dans FROM ou XREL, et le graphique qui en résulte ne contient pas les valeurs de relation.
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%'
Extraction des relations nulles ou vides
Cette requête renvoie les services qui n'ont pas d'employés ainsi que les employés qui ne font pas partie d'un service. Normalement, l'application doit assigner les employés à l'un des services. xrel a pour but de définir la relation e.dept (et le rôle inversé d.emps) dans le schéma de graphique.
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
Paramètre d'entrée de collection
Une collection de beans enterprise peut être transmise en tant qu'argument d'entrée au médiateur d'EJB et référencée dans la clause FROM. L'utilisation d'un paramètre de collection permet de construire un datagraphe à partir d'une collection utilisateur de beans enterprise déjà activés.
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
La requête indiquée se répète dans la collection de beans Dept et de beans Emp associés, appliquant les prédicats de la requête et construisant le graphique de données. Les valeurs sont obtenues à partir des valeurs actuelles des beans. Voici un exemple de programme utilisant un paramètre de collection d'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.  
   }
Utilisation de MediatorAdapter

Dans cet exemple, l'adaptateur traite des événements CREATE pour un objet de données EMP. Les attributs de nom et de salaire sont extraits de l'objet de données et transmis à la méthode create sur EmpLocalHome.

La méthode create renvoie une instance d'EJB Emp et la valeur de clé primaire est recopiée dans l'objet de données. L'appelant peut alors obtenir la valeur de clé générée. Après traitement, l'adaptateur renvoie la valeur true. L'adaptateur ignore toutes les autres modifications, qui sont traitées par le médiateur d'EJB.

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(){}
}

Icône indiquant le type de rubrique Rubrique de tâche



Icône d'horodatage Dernière mise à jour: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tejb_ejbmeduse
Nom du fichier : tejb_ejbmeduse.html