Utilizando o serviço de consulta dinâmica

Há momentos no processo de desenvolvimento em que é possível preferir usar o serviço de consulta dinâmica em vez de o serviço de consulta de Enterprise JavaBeans (EJB) regular (o qual pode ser referido como consulta de implementação). Durante o teste, por exemplo, o serviço de consulta dinâmica pode ser utilizado no tempo de execução do aplicativo, desta forma, você não precisa reimplementar seu aplicativo.

Sobre Esta Tarefa

A seguir estão as razões comuns para usar o serviço de consulta dinâmica em vez do serviço de consulta normal do EJB:
  • Você precisa definir uma consulta de maneira programática no tempo de execução do aplicativo, em vez de defini-la na implementação.
  • Você precisa retornar vários campos CMP ou CMR de uma consulta. (As consultas de implementação permitem que apenas um elemento único seja especificado na cláusula SELECT.) Para obter informações adicionais, consulte o tópico Exemplo: Consultas EJB.
  • Você deseja retornar uma expressão computada na consulta.
  • Você deseja usar métodos de objetos de valor ou métodos de bean na instrução de consulta. Para obter informações adicionais, consulte o tópico Expressões de Caminho.
  • Você deseja testar uma consulta do EJB de forma interativa durante o desenvolvimento, mas não deseja implementar o aplicativo repetidamente cada vez que atualizar um localizador ou uma consulta select.

A API de consulta dinâmica é um bean de sessão sem preservação de estado. A utilização dele é semelhante à utilização de qualquer outro bean do aplicativo EJB J2EE. Ela está incluída no com.ibm.websphere.ejbquery do pacote de APIs.

O bean de consulta dinâmica possui uma interface local e uma remota. Se desejar retornar referências remotas de EJB da consulta ou se a instrução da consulta contiver métodos remotos, você deverá usar a interface remota da consulta:

interface remota = com.ibm.websphere.ejbquery.Query
interface remota de início = com.ibm.websphere.ejbquery.QueryHome

Se desejar retornar referências locais do EJB da consulta ou se a instrução da consulta contiver métodos locais, você deverá usar a interface local da consulta:

interface local = com.ibm.websphere.ejbquery.QueryLocal
interface local de início = com.ibm.websphere.ejbquery.QueryLocalHome

Como ela utiliza menos memória do servidor de aplicativos, a interface local assegura melhor desempenho do EJB global do que a interface remota.

Procedimento

  1. Verifique se o arquivo do aplicativo query.ear está instalado no servidor de aplicativos no qual o aplicativo deve executar, se este servidor for diferente do servidor de aplicativos padrão criado durante a instalação do produto.
    O arquivo query.ear está localizado no diretório app_server_root, em que <WAS_HOME> é o local do WebSphere Application Server. O programa de instalação do produto instala o arquivo query.ear no servidor de aplicativos padrão utilizando um nome JNDI de
    com/ibm/websphere/ejbquery/Query
    (Você ou o administrador do sistema pode alterar este nome.)
  2. Configure a autorização para os métodos executeQuery(), prepareQuery() e executePlan() nas interfaces de consulta dinâmica local e remota para controlar o acesso a dados confidenciais. (Esta etapa será necessária apenas se o aplicativo exigir segurança.)

    Como você não pode controlar quais nomes ASN, campos CMP ou campos CMR podem ser utilizados em uma consulta EJB dinâmica, você ou o administrador do sistema deve colocar restrições sobre o uso dos métodos. Se, por exemplo, for permitido que um usuário execute o método executeQuery, ele ou ela poderá executar qualquer consulta dinâmica válida. Em um ambiente de produção, você certamente desejará restringir o acesso aos métodos da interface de consulta remota.

  3. Grave a consulta dinâmica como parte do código do cliente aplicativo. É possível consultar os tópicos de exemplo, Exemplo de Consulta Dinâmica da Interface Remota e Exemplo de Consulta Dinâmica da Interface Local, como modelos de consulta; eles ilustram quais instruções de importação usar.
  4. Se o CMP que você deseja consultar estiver em um módulo diferente, será necessário:
    1. Fazer uma consulta remota em query.ear
    2. Mapear o arquivo query.ear para o servidor em que o bean CMP consultado está instalado.
  5. Compile e execute o programa cliente com o arquivo qryclient.jar no classpath.

Exemplo

Usando a interface remota para consulta Dinâmica.

Ao executar uma consulta dinâmica EJB (Enterprise JavaBeans) utilizando a interface remota, você está chamando o método executeQuery na interface Query. O método executeQuery tem um atributo de transação REQUIRED para esta interface; portanto, não você deve estabelecer explicitamente um contexto de transação para a execução da consulta.

Ao executar uma consulta dinâmica EJB (Enterprise JavaBeans) utilizando a interface remota, você está chamando o método executeQuery na interface Query. O método executeQuery tem um atributo de transação REQUIRED para essa interface; portanto, não é necessário estabelecer explicitamente um contexto de transação para a execução da consulta.

Inicie com as seguintes instruções de importação:

import com.ibm.websphere.ejbquery.QueryHome;
import com.ibm.websphere.ejbquery.Query;
import com.ibm.websphere.ejbquery.QueryIterator;
import com.ibm.websphere.ejbquery.IQueryTuple;
import com.ibm.websphere.ejbquery.QueryException;

Em seguida, grave sua instrução de consulta no formato de uma cadeia, como no exemplo a seguir que recupera os nomes e referências ejb para funcionários com remuneração baixa:

String query = 
"select e.name as name , object(e) as emp from EmpBean e where e.salary < 50000"; 

Crie um objeto Query, obtendo uma referência da classe QueryHome. (Essa classe define o método executeQuery.) Observe que por questão de simplicidade, o exemplo a seguir utiliza o nome de JNDI da consulta dinâmica para o objeto Query:

InitialContext ic = new InitialContext(); 

Object obj =  ic.lookup("com/ibm/websphere/ejbquery/Query");

QueryHome  qh = 
 ( QueryHome) javax.rmi.PortableRemoteObject.narrow( obj, QueryHome.class );
Query qb = qh.create();

Em seguida, você deve especificar um tamanho máximo para o conjunto de resultados da consulta, que é definido no objeto QueryIterator, que está incluído no QueryIterator da classe. Em seguida, você deve especificar um tamanho máximo para o conjunto de resultados da consulta, que está definido no objeto QueryIterator, que está incluído no pacote de APIs QueryIterator. Este exemplo define o tamanho máximo do conjunto de resultados como 99:

QueryIterator it = qb.executeQuery(query, null, null ,0, 99 );
O iterador contém uma coleta de objetos IQueryTuple, que são registros dos valores da coleta de retorno. Correspondendo aos critérios de nossa instrução de consulta de exemplo, cada tupla desse cenário contém um valor de nome e um valor de objeto(e). Para exibir o conteúdo desse resultado de consulta, utilize o seguinte código:
while (it.hasNext() ) { 
	IQueryTuple tuple = (IQueryTuple) it.next();
	System.out.print( it.getFieldName(1) );
	String s = (String) tuple.getObject(1);
	System.out.println( s);
	System.out.println( it.getFieldName(2) );
	Emp e = ( Emp) javax.rmi.PortableRemoteObject.narrow( tuple.getObject(2), Emp.class );
	System.out.println( e.getPrimaryKey().toString());
}
A saída do programa pode ser semelhante à seguinte:
name Bob 
emp 1001
name Dave
emp 298003
...
Por último, capture e processe quaisquer exceções. Uma exceção pode ocorrer devido a um erro de sintaxe na instrução de consulta ou de um erro de processamento no tempo de execução. O exemplo a seguir captura e processa estas exceções:
} catch (QueryException qe) {
    System.out.println("Query Exception "+ qe.getMessage() );
}

Manipulando grandes coletas de resultados para a consulta da interface remota

Se pretende que sua consulta retorne uma grande coleta, você tem a opção de programá-la para retornar resultados em várias quantidades menores mais gerenciáveis. Utilize os parâmetros skipRow e maxRow do método remoto executeQuery para recuperar a resposta em partes. Por exemplo:

int skipRow=0;
int maxRow=100;
QueryIterator it = null;
do {
	it = qb.executeQuery(query, null, null ,skipRow, maxRow );
	while (it.hasNext() ) { 
	// display result 
	skipRow = skipRow + maxRow;
}
} while ( ! it.isComplete() ) ;
Usando a interface local para consulta Dinâmica.

Ao executar uma consulta dinâmica EJB (Enterprise JavaBeans) utilizando a interface local, você está chamando o método executeQuery na interface QueryLocal. Esta interface não inicia uma transação para o método; portanto, você deve estabelecer explicitamente um contexto de transação para executar a consulta.

Nota: Para estabelecer um contexto de transação, o exemplo a seguir chama os métodos begin() e commit(). Uma alternativa para o uso desses métodos é simplesmente incorporar seu código de consulta em um método EJB executado em um contexto de transação.

Inicie seu código de consulta com as instruções de importação a seguir:

import com.ibm.websphere.ejbquery.QueryLocalHome;
import com.ibm.websphere.ejbquery.QueryLocal;
import com.ibm.websphere.ejbquery.QueryLocalIterator;
import com.ibm.websphere.ejbquery.IQueryTuple;
import com.ibm.websphere.ejbquery.QueryException;

Em seguida, grave sua instrução de consulta no formato de uma cadeia, como no exemplo a seguir que recupera os nomes e referências ejb para funcionários com remuneração baixa:

String query = 
"select e.name, object(e) from EmpBean e where e.salary < 50000 ";

Crie um objeto QueryLocal, obtendo uma referência da classe QueryLocalHome. (Esta classe define o método executeQuery.) Observe que, no exemplo a seguir, ejb/query é utilizado como uma referência EJB local que aponta para o nome de JNDI da consulta dinâmica (com/ibm/websphere/ejbquery/Query):

InitialContext ic = new InitialContext(); 
   QueryLocalHome  qh =  ( LocalQueryHome) ic.lookup( "java:comp/env/ejb/query" );
QueryLocal qb = qh.create();

A última parte do código inicia uma transação, chama o método executeQuery e exibe os resultados da consulta. A classe QueryLocalIterator é instanciada, porque ela define o conjunto de resultados da consulta. A classe está incluída no pacote de API da Classe QueryIterator. Tenha em mente que o iterador perde a validade no final da transação, você deverá usar o iterador no mesmo escopo da transação que a chamada executeQuery.

userTransaction.begin();
QueryLocalIterator it = qb.executeQuery(query, null, null);
while (it.hasNext() ) { 
	IQueryTuple tuple = (IQueryTuple) it.next();
	System.out.print( it.getFieldName(1) );
	String s = (String) tuple.getObject(1);
	System.out.println( s);
	System.out.println( it.getFieldName(2) );
	EmpLocal e = ( EmpLocal ) tuple.getObject(2);
	System.out.println( e.getPrimaryKey().toString());
}
userTransaction.commit();

Na maioria das situações, o objeto QueryLocalIterator é orientado a demanda. Ou seja, ele faz com que dados sejam retornados de forma incremental: para cada recuperação de registro do banco de dados, o método next() deve ser chamado no iterador. (Podem existir situações em que o iterador não é orientado a demanda. Para obter informações adicionais, consulte a subseção Interfaces de consulta local do tópico Considerações de desempenho de consulta dinâmica.)

Como o conjunto de resultados da consulta completo é incrementalmente materializado na memória do servidor de aplicativos, é possível controlar facilmente seu tamanho. Durante uma execução de teste, por exemplo, é possível decidir que o retorno de apenas algumas tuplas do resultado de pesquisa será necessário. Nesse caso, você deve usar uma chamada do método close() no objeto QueryLocalIterator para fechar o loop da consulta. Fazendo isso, você libera recursos SQL utilizados pelo iterador. Caso contrário, estes recursos não são liberados até o conjunto total de resultados ser acumulado na memória ou até a transação terminar.


Í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=tque_dynamic
Nome do arquivo: tque_dynamic.html