Utilización de Data Mediator Service de EJB para acceso a datos

En los pasos siguientes se utilizan ejemplos de código para describir una instancia simple de cómo crear los metadatos DMS (Data Mediator Service) del EJB (Enterprise JavaBeans).

Procedimiento

  1. Una instancia de mediador se crea con uno de los métodos de creación de la fábrica de mediadores (com.ibm.websphere.sdo.mediator.ejb.MediatorFactory) como en el ejemplo siguiente:
    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. Existen 3 formas distintas del método createMediator. Los argumentos se explican de la siguiente manera:
    createMediator( query, parms) 
    createMediator( query, parms, schema )
    createMediator( query, parms, schema,  typeMap,  pattern)
    Tabla 1. Argumentos del método createMediator. Los argumentos se explican en la tabla siguiente:
    Tipo Argumento Descripción
    Serie query matriz de sentencias de consulta de EJB
    Objeto parms valores de parámetros de entrada de sentencias de consulta
    Eclass* esquema EClass del DataObject raíz
    Map* typeMap a java.util.Map que correlaciona nombres de esquema abstractos de EJB de la sentencia de consulta en nombres de Eclass
    int* pattern patrón utilizado para la contención
     
    * sólo se utiliza cuando se utiliza el esquema proporcionado del llamante

Ejemplo

Utilización de argumentos de consulta con el mediador de EJB

Los siguientes ejemplos muestran cómo puede ajustar los argumentos de consulta del mediador de EJB (Enterprise JavaBeans).

Ejemplo sencillo
Esta consulta devuelve un DataGraph que contiene varias instancias de DataObjects de tipo (nombre de Eclass) Emp. Los atributos de objeto de datos son empid (idempleado) y name (nombre) y sus tipos de datos corresponden a los tipos de campo CMP (persistencia gestionada por contenedor).
select  e.empid, e.name 
from Emp as e 
where e.salary > 100
El DataGraph serializado devuelto en formato XML se parece a esto:
<?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>
Parámetros de consulta
Este ejemplo muestra cómo se pueden utilizar los marcadores de parámetro. Recuerde que la sintaxis de marcadores de parámetro de consultas EJB es un símbolo de cerrar interrogación seguido de un número (?n). Cuando llama al método getGraph ( ) en el EJBMediator, puede pasar de modo opcional una matriz de valores. ?n hace referencia al valor de parm[n-1]. La matriz de valores también se puede pasar en la llamada a factory para crear el EJBMediator. Los parámetros pasados en getGraph( ) alteran temporalmente los parámetros pasados en la llamada a create.
select  e.empid, e.name 
from Emp as e 
where e.salary > ?1 
Devolución de expresiones y métodos
Este ejemplo ilustra que los atributos de objeto de datos pueden ser valores devueltos de expresiones de consulta. Las expresiones de consulta de EJB incluyen expresiones aritméticas, de fecha y hora, de vía de acceso y métodos. Los argumentos de entrada y los valores de retorno de los métodos quedan restringidos a la lista de tipos de datos soportados. Consulte el tema sobre la sintaxis de consulta del mediador de EJB. Los objetos de datos que contienen atributos actualizados derivados de expresiones provocan excepciones durante el proceso de applyChanges a no ser que el usuario haya proporcionado un MediatorAdapter para manejar el cambio.
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
Los nombres de atributo de objeto de datos se derivan de los nombres de campo CMP pero se pueden alterar temporalmente utilizando la palabra clave AS en la consulta. Cuando especifica una expresión, debería utilizar siempre la palabra clave AS para dar un nombre a la expresión.
Sintaxis de *
La notación e.* es un fragmento abreviado para especificar todos los campos CMP (pero no las relaciones gestionadas por contenedor) de los EJB. La consulta siguiente significa lo mismo que e.empid, e.name e.salary, e.bonus.
select e.* from Emp as e
Sin clave primaria en la cláusula SELECT
Este ejemplo muestra una consulta que no devuelve el campo de clave primaria. No obstante, a no ser que el objeto de datos contenga todos los campos de clave primaria para un EJB, el mediador no podrá procesar las actualizaciones en el DataGraph. Esto es porque es necesaria la clave primaria para traducir los cambios en SQL (Lenguaje de consulta estructurada) o para convertir referencias de DataObject a referencias de EJB. Se produce una excepción cuando applyChanges intenta realizar la ejecución.
select e.name, e.salary from Emp as e
Order by
Los DataObjects se pueden ordenar.
select d.* from Dept d  order by d.name
	select e.* from in(d.emps) e order by e.empid desc
Esto provoca que los objetos Dept se ordenen por nombre y los objetos Emp dentro de cada Dept se ordenen por empid en orden descendente.
Navegación por relaciones de varios valores
Esta consulta compuesta devuelve un DataGraph con clases Dept y Emp de DataObject. La forma del DataGraph refleja las expresiones de vía de acceso utilizadas en las cláusulas 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
En este caso Dept es el nodo raíz del DataGraph y hay una referencia de varios valores de Dept a Emp como se muestra:
<?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>
Más sobre parámetros de consulta
Las condiciones de búsqueda se pueden especificar en cualquier consulta. Los argumentos de entrada son globales a la consulta y se puede hacer referencia a éstos por número en cualquier parte de la consulta compuesta. En el ejemplo anterior, los argumentos de consulta pasados en la llamada a create o getGraph deben estar en orden {valor de deptno, valor de salary, valor de deptno}.
select d.* from Dept as d 
   where d.deptno between ?1 and ?3 
select e.* from in(d.emps) e  
   where e.salary < ?2
Navegación por vías de acceso con varias relaciones
La consulta siguiente navega por la vía de acceso compuesta de relaciones de EJB Dept.projs y Project.tasks y devuelve DataObjects para Dept, Emp y Project que contienen los campos CMP seleccionados.
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
El gráfico de datos resultante en formato XML se muestra aquí.
<?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>
Navegación por varias vías de acceso
A continuación figura una consulta del mediador que devuelve un DataGraph con DataObjects para Dept con empleados relacionados y una segunda vía de acceso que recupera proyectos y tareas relacionados.
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
El DataGraph devuelto se parece a éste:
<?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>
Navegación por relaciones de un solo valor
Lo importante a señalar aquí es que aún cuando Emp sea el objeto de datos raíz del gráfico, varios objetos de datos Emp se relacionarán con el mismo objeto de datos Dept. Así que, a diferencia de los ejemplos anteriores, el gráfico de datos no tiene una forma de árbol cuando consulta las instancias del objeto de datos, existen varios objetos Emp raíz relacionados con el mismo objeto Dept. Pero después de todo es un gráfico de datos, no un árbol datos. Recuerde que las consultas del mediador permiten expresiones de vía de acceso de un solo valor en la cláusula FROM. Este es un cambio de la sintaxis de consulta de EJB estándar.
select e.empid, e.name  from Emp e 
select d.deptno, d.name  from in(e.dept) d 
Y el DataGraph en formato XML se parece a esto:
<?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>
Expresiones de vía de acceso en la cláusula SELECT
Esta consulta es similar a la anterior (las dos consultas devuelven datos del empleado junto con el número de departamento y el nombre) pero recuerde que el gráfico de datos contiene sólo un tipo de objeto de datos en esta consulta (frente a dos de la consulta anterior). Los campos deptno y el campo name son de sólo lectura porque provienen de una expresión de vía de acceso de la cláusula SELECT y no son campos CMP del 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 
Navegación por relaciones de muchos a muchos
La relación de Emp a Task se considera una relación de muchos a muchos. La siguiente consulta recupera empleados, tareas y proyectos. Sólo se da una única aparición de cualquier tarea DataObject determinada en el DataGraph, incluso si se puede relacionar con muchos empleados.
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
Varios enlaces entre objetos de datos
El mediador de EJB le permite recuperar datos basados en relaciones y utilizar el mandato XREL para construir una o más relaciones adicionales basadas en datos ya recuperados. El mediador también permite la recuperación de datos basados en ASNname y la posterior construcción de una o más relaciones basadas en los datos recuperados utilizando el mandatoXREL. La siguiente consulta recupera departamentos, empleados que trabajan en los departamentos y empleados que gestionan los departamentos.
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
La segunda y tercera sentencias select devuelven instancias de DataObject Emp. Es posible que la misma instancia Emp se recupere a través de las relaciones d.emps y d.manager. El mediador de EJB crea una instancia Emp, pero crea ambas relaciones.
La siguiente consulta se procesa del siguiente modo. Los DataObjects Dept se crean a partir de los datos de la primera consulta. Los DataObjects Emp se crean a partir de los datos de la segunda consulta. A continuación, se crean las relaciones del gráfico para cualquier relación utilizada en la cláusula FROM o la palabra clave XREL. Durante la creación de relaciones, no se recuperan datos adicionales. En este ejemplo, un empleado que trabaja en un departamento denominado Dev aparece en el DataGraph. Si este empleado gestiona un departamento denominado Sales, la referencia manages está vacía. El departamento Dev se ha recuperado en la primera consulta, no así el departamento 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
Las relaciones emps y manager se construyen en función de las instancias de DataObject creadas a partir de las consultas. Un empleado cuyo nombre es "Dev", pero que trabaja en el departamento "Sales", tendrá una relación dept nula en el gráfico.
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
El siguiente ejemplo muestra la recuperación de objetos de datos para todos los empleados, objetos y tareas de un determinado departamento y el enlace de los empleados con las tareas.
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 una tarea se asigna a un empleado del departamento 42, ese enlace aparece en el gráfico de datos. Si la tarea se asigna a un empleado que no sea del departamento 42, el enlace no aparece en gráfico de datos porque la consulta ha filtrado el objeto de datos. Una palabra clave XREL puede ir seguida de una o más relaciones de EJB. Las relaciones bidireccionales pueden hacer referencia a cualquier nombre de rol. El origen y el destino de la relación deben recuperarse a partir de una o más consultas.

Recuperación de objetos no relacionados
La siguiente consulta recupera Dept y 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 siguiente consulta recupera Dept y Emps. Incluso si existen relaciones entre Dept y Emp (es decir, mgr y emps), no se utiliza ninguna en FROM o XREL de modo que el gráfico resultante no contiene los valores de relación.
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%'
Recuperación de relaciones nulas o vacías
Esta consulta devuelve los departamentos sin empleados y los empleados sin departamento. Es probable que la aplicación desee asignar los empleados a uno de los departamentos. El objetivo de xrel es definir la relación e.dept (y el rol inverso d.emps) en el esquema de gráfico.
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
Parámetro de entrada de tipo collection
Se puede pasar una colección de enterprise beans como argumento de entrada al mediador de ejb y hacer referencia a éstos en la cláusula FROM. El uso de parámetros collection satisface el requisito de construir un gráfico de datos a partir de una colección de usuarios de enterprise beans ya activados.
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 consulta indicada itera por la colección de beans Dept y beans Emp relacionados aplicando los predicados de la consulta y construyendo el gráfico de datos. Los valores se obtendrán de los valores actuales de los beans. Ejemplo de un programa que utiliza un parámetro collection de ejb.
// este método se ejecuta en un contexto de EJB y dentro de un ámbito de transacción   
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); // proporciona a todos un aumento del 10% 
      }

      // crear el parámetro collection de consulta
      Collection c = new LinkedList();
      c.add(dept);
      Object[] parms = new Object[] { c};  // poner la colección de ejb en la matriz parms.

      // la colección que contiene el EJB dept se pasa al mediador de EJB

      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;
      // el DataGraph contiene la información de sueldo actualizada y 
      //  todavía no comprometida.  Los datos Dept y Emp se capturan mediante
      // instancias EJB activas en EJBContainer.
      //  Los datos del proyecto se recuperan de la base de datos utilizando 
      //   relaciones gestionadas por contenedor.  
   }
Uso de MediatorAdapter

En este ejemplo, el adaptador procesa sucesos CREATE para objetos de datos EMP. Los atributos name (nombre) y salary (sueldo) se extraen del objeto de datos y se pasan al método create en el EmpLocalHome.

El método create devuelve una instancia del EJB Emp y el valor de clave primaria se copia de nuevo al DataObject. El llamante pueden obtener entonces el valor de clave generado. Después del proceso, el adaptador devuelve un valor de true. El adaptador ignora todos los demás cambios y los procesa el mediador de 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;

// ejemplo de la clase Adapter que llama a un método create de EJB.

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() ); // establecer la clave primaria de SDO
				return true;	
      			} catch(Exception e){ // aquí va el código de manejo de errores 
      }
		}
		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) { // aquí va el código de manejo de errores
      }
  }

  	public void end(){}
}

Icon that indicates the type of topic Task topic



Timestamp icon Last updated: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tejb_ejbmeduse
File name: tejb_ejbmeduse.html