Usando o Serviço Mediador de Dados EJB para Acesso a Dados

As seguintes etapas usam as amostras de código para descrever uma instância simples de como criar os metadados DMS (data mediator service) EJB (Enterprise JavaBeans).

Procedimento

  1. Uma instância do mediador é criada utilizando-se um dos métodos create no depósito de informações do provedor do mediador (com.ibm.websphere.sdo.mediator.ejb.MediatorFactory), como no exemplo a seguir
    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. Há 3 formas diferentes do método createMediator. Os argumentos são explicados da seguinte forma:
    createMediator( query, parms) 
    createMediator( query, parms, schema )
    createMediator( query, parms, schema,  typeMap,  pattern)
    Tabela 1. createMediator method arguments. Os argumentos são explicados na tabela a seguir:
    Type Argumento Descrição
    Sequência de Caracteres query matriz de instruções de consulta do EJB
    Objeto parms valores para parâmetros de entrada das instruções de consulta
    Eclass* esquema EClass do DataObject raiz
    Map* typeMap um java.util.Map que mapeia Nomes de Esquemas Abstratos do EJB da instrução de consulta para nomes de Eclass
    int* pattern o padrão utilizado para contenção
     
    * utilizado somente ao utilizar esquema fornecido pelo responsável pela chamada

Exemplo

Usando os argumentos de consulta com o mediador EJB.

Os exemplos a seguir mostram como é possível fazer um ajuste fino dos argumentos de consulta do mediador Enterprise JavaBeans (EJB).

Um Exemplo Simples
Essa consulta retorna um DataGraph que contém várias instâncias de DataObjects do tipo (nome Eclass) Emp. Os atributos do objeto de dados são empid e name e seus tipos de dados correspondem aos tipos de campos CMP (Container-Managed Persistence).
select  e.empid, e.name 
from Emp as e 
where e.salary > 100
O DataGraph retornado serializado em seu formato XML se parece com o seguinte:
<?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
Esse exemplo mostra como os marcadores de parâmetros podem ser utilizados. Lembre-se de que a sintaxe para os marcadores de parâmetro em uma consulta EJB é um ponto de interrogação seguido de um número (?n). Ao chamar o método getGraph ( ) no EJBMediator você pode, opcionalmente, transmitir uma matriz de valores. ?n se refere ao valor parm[n-1]. A matriz de valores também pode ser transmitida na chamada do depósito de informações do provedor para criar o EJBMediator. Os parâmetros transmitidos no getGraph( ) substituem quaisquer parâmetros transmitidos na chamada de criação.
select  e.empid, e.name 
from Emp as e 
where e.salary > ?1 
Retornando Expressões e Métodos
Esse exemplo ilustra que os atributos de objetos de dados podem ser valores de retorno de expressões de consulta. As expressões de consulta EJB incluem aritmética, data-hora, expressões de caminho e métodos. Os argumentos de entrada e valores de retorno de métodos são restritos à lista de tipos de dados suportados; consulte o tópico Sintaxe de Consulta do Mediador EJB. Um objeto de dados que contém um atributo atualizado derivado de uma expressão faz com que uma exceção ocorra durante o processo applyChanges, a menos que o usuário tenha fornecido um MediatorAdapter para manipular a alteração.
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
Os nomes de atributos do objeto de dados são derivados dos nomes de campo CMP, mas podem ser substituídos utilizando a palavra-chave AS na consulta. Ao especificar uma expressão, a palavra-chave AS sempre deve ser utilizada para fornecer um nome à expressão.
A sintaxe *
A notação e.* é um atalho para especificar todos os campos CMP (mas não os Container-Managed Relationships) para um EJB. A seguinte consulta significa o mesmo que e.empid, e.name e.salary, e.bonus.
select e.* from Emp as e
Nenhuma Chave Principal na Cláusula select
Esse exemplo mostra uma consulta que não retorna o campo da chave principal. No entanto, a menos que o objeto de dados contenha todos os campos de chave principal para um EJB, as atualizações no DataGraph não podem ser processadas pelo mediador. Isso ocorre porque a chave principal é necessária para traduzir as alterações em SQL (Structured Query Language) ou converter as referências de DataObject para referências EJB. Exceção quando applyChanges tenta ser executado.
select e.name, e.salary from Emp as e
Ordenar por
Os DataObjects podem ser classificados.
select d.* from Dept d  order by d.name
select e.* from in(d.emps) e order by e.empid desc
Isso resulta em objetos Dept sendo classificados por nome e objetos Emp dentro de cada Dept sendo classificados por empid na ordem descendente.
Navegando em um Relacionamento Multiavaliado
Essa consulta composta retorna um DataGraph com classes DataObject Dept e Emp. O formato do DataGraph reflete as expressões de caminho utilizadas nas 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
Nesse caso Dept é o nó raiz no DataGraph e há uma referência multi-avaliada de Dept para Emp, conforme mostrado:
<?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>
Mais Detalhes sobre Parâmetros de Consulta
As condições de procura podem ser especificadas em qualquer consulta. Os argumentos de entrada são globais para a consulta e podem ser referidos por número em qualquer local da consulta composta. No exemplo anterior, os argumentos de consulta transmitidos na chamada create ou getGraph devem estar em ordem { 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
Navegando em um Caminho com Vários Relacionamentos
A seguinte consulta navega no caminho composto de relacionamentos EJB Dept.projs e Project.tasks e retorna DataObjects para Dept, Emp e Project que contêm campos CMP selecionados.
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
O gráfico de dados resultante no formato XML é mostrado aqui.
<?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>
Navegando em Vários Caminhos
Segue uma consulta de mediador que retorna um DataGraph com DataObjects para Dept com funcionários relacionados e um segundo caminho que recupera os projetos e tarefas 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
O DataGraph retornado é semelhante ao seguinte:
<?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>
Navegando em um Único Relacionamento Avaliado
O importante a ser observado aqui é que mesmo que Emp seja o objeto de dados raiz no gráfico, vários objetos de dados Emp serão relacionados ao mesmo objeto de dados Dept. Portanto, ao contrário dos exemplos anteriores, o gráfico de dados não possui um formato de árvore quando você examina instâncias do objeto de dados - existem múltiplos objetos Emp raiz relacionados ao mesmo objeto Dept. Mas, apesar de tudo, ele é um gráfico de dados e não uma árvore de dados. Observe que as consultas do mediador permitem expressões de caminho avaliadas únicas na cláusula FROM. Esta é uma mudança da sintaxe de consulta EJB padrão.
select e.empid, e.name  from Emp e 
select d.deptno, d.name  from in(e.dept) d 
E o DataGraph no formato XML se parece com:
<?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>
Expressões de Caminho na Cláusula SELECT
Essa consulta é semelhante à anterior (ambas as consultas retornam dados do funcionário juntamente com o nome e o número do departamento), mas observe que o gráfico de dados contém apenas um tipo de objeto de dados nessa consulta (vs. dois na consulta anterior). Os campos deptno e o campo de nome são lidos apenas porque são resultados de uma expressão de caminho na cláusula SELECT e não são campos CMP do Emp EJB.
select  e.empid as EmplId , e.name as EmpName ,
		 e.dept.deptno as DeptNo , e.dept.name as DeptName
from Emp as e
Navegando em um Relacionamento many: many
O relacionamento Emp para Task é considerado um relacionamento many:many. A seguinte consulta recupera funcionários, tarefas e projetos. Existe apenas uma única ocorrência de qualquer DataObject de tarefa específica no DataGraph, embora ela possa estar relacionada a vários funcionários.
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
Vários Links entre Objetos de Dados
O mediador EJB permite recuperar dados com base em relacionamentos e utilizar o comando XREL para construir um ou mais relacionamentos adicionais com base nos dados já recuperados. O mediador também permite a recuperação de dados com base no ASNname e, então, a construção de um ou mais relacionamentos com base nos dados recuperados utilizando o comando XREL. A seguinte consulta recupera departamentos, funcionários que trabalham nos departamentos e funcionários que gerenciam os 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
A segunda e terceira cláusulas select retornam instâncias do Emp DataObject. É possível que a mesma instância Emp seja recuperada através dos relacionamentos d.emps e d.manager. O mediador EJB cria uma instância Emp, mas cria ambos os relacionamentos.
A seguinte consulta é processada como segue. Dept DataObjects são criados a partir dos dados na primeira consulta. Emp DataObjects são criados a partir dos dados na segunda consulta. Os relacionamentos no gráfico são então construídos para qualquer relacionamento utilizado na cláusula FROM ou em uma palavra-chave XREL. Durante a construção do relacionamento, nenhum dado adicional é recuperado. Neste exemplo, um funcionário que trabalha em um departamento chamado Dev aparece no DataGraph. Se esse funcionário gerenciar um departamento chamado Sales, a referência manages ficará vazia. O departamento Dev foi recuperado na primeira consulta, não no 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
O relacionamento emps e manager é construído com base nas instâncias DataObject criadas a partir das consultas. Um funcionário cujo nome é "Dev", mas que trabalha no departamento "Sales" terá um relacionamento de departamento nulo no 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
O próximo exemplo mostra a recuperação de objetos de dados para todos os funcionários, projetos e tarefas de um determinado departamento e o vínculo dos funcionários com as tarefas.
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

Se uma tarefa for designada a um funcionário no departamento 42, então, esse link aparecerá no gráfico de dados. Se a tarefa for designada para um funcionário que não está no departamento 42, então, esse link não aparecerá no gráfico de dados porque o objeto de dados foi filtrado pela consulta. Uma palavra-chave XREL pode ser seguida por um ou mais relacionamentos EJB. Relacionamentos bidirecionais podem se referir a qualquer nome de função. Tanto a origem como o destino do relacionamento devem ser recuperados por uma ou mais consultas.

Recuperando Objetos Não Relacionados
A seguinte consulta recupera Dept e 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'
A seguinte consulta recupera Dept e Emps. Embora haja relacionamentos entre Dept e Emp (chamados mgr e emps), nenhum dos relacionamentos é utilizado em FROM ou XREL e, portanto, o gráfico resultante não contém os valores de relacionamento.
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%'
Recuperando Relacionamentos Nulos ou Vazios
Essa consulta retorna departamentos que não têm funcionários e funcionários sem departamento. Presume-se que o aplicativo deseje designar os funcionários a um dos departamentos. O objetivo de xrel é definir o relacionamento e.dept (e função inversa d.emps) para o 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 Coleta
Uma coleta dos beans corporativos pode ser transmitida como um argumento de entrada para o mediador ejb e referenciada na cláusula FROM. Utilizar o parâmetro de coleta satisfaz o requisito para construir o gráfico de dados de uma coleta de usuário dos beans corporativos já ativados.
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
A consulta fornecida itera por meio da coleta de beans Dept e beans Emp relacionados, aplicando os predicados da consulta e construindo o gráfico de dados. Os valores serão obtidos dos valores atuais dos beans. Um exemplo de um programa que utiliza um parâmetro de coleta ejb.
// esse método é executado em um contexto EJB e dentro do escopo de transação   
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); // dar aumento de 10% a alguém 
      }

      // criar o parâmetro de coleta de consulta
      Collection c = new LinkedList();
      c.add(dept);
      Object[] parms = new Object[] { c};  // colocar coleta ejb na matriz de parâmetro.

      // coleta que contém o dept EJB é transmitida ao Mediador 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;
      // O DataGraph contém informações atualizadas e ainda não consolidadas 
      //  sobre o salário.  Dept and Emp data is fetched through
      // EJB instances active in the EJBContainer. 
      //  Os dados de projeto foram recuperados do banco de dados utilizando
      //   relacionamentos gerenciados por contêiner.  
   }
Usando MediatorAdapter

Nesse exemplo, o adaptador processa os eventos CREATE para um objeto de dados EMP. Os atributos de nome e de salário são extraídos do objeto de dados e transmitidos para o método create no EmpLocalHome.

O método create retorna uma instância Emp EJB e o valor da chave principal é copiado de volta para o DataObject. O responsável pela chamada pode, então, obter o valor de chave gerado. Após o processamento, o adaptador retorna um valor true. Todas as outras alterações são ignoradas pelo adaptador e processadas pelo Mediador 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;

// exemplo de classe do Adaptador que chama um método create 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() ); // definir chave principal no SDO
				return true;	
      } catch (Exception e){ // o código de manipulação de erro ficará aqui 
      }
		}
		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) { // o código de manipulação de erro ficará aqui
      }
  }

  public void end(){}
}

Ícone que indica o tipo de tópico Tópico de Tarefa



Ícone de registro de data e hora Última atualização: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tejb_ejbmeduse
Nome do arquivo: tejb_ejbmeduse.html