Utilización del servicio de consulta dinámica

Hay momentos en el proceso de desarrollo en que quizá prefiera utilizar el servicio de consulta dinámica en lugar del servicio de consultas de Enterprise JavaBeans (EJB) normal (al que puede denominar consulta de despliegue). Por ejemplo, durante las pruebas el servicio de consulta dinámica puede utilizar en el tiempo de ejecución de la aplicación, de modo que no tenga que volver a desplegar la aplicación.

Acerca de esta tarea

Los siguientes son motivos frecuentes para utilizar el servicio de consulta dinámica, en lugar del servicio de consulta EJB normal:
  • Es necesario definir mediante programación una consulta en tiempo de ejecución de la aplicación, en lugar de hacerlo durante el despliegue.
  • Es necesario devolver varios campos CMP o CMR desde una consulta (las consultas de despliegue sólo permiten que en la cláusula SELECT se especifique un único elemento). Si desea más información, consulte el tema Ejemplo: consultas EJB.
  • Si quiere devolver una expresión calculada en la consulta
  • Si quiere utilizar métodos de objetos de valor o métodos bean en sentencias de consulta. Si desea más información, consulte el tema sobre las expresiones path.
  • Si quiere probar de forma interactiva una consulta EJB durante el despliegue, pero no quiere desplegar la aplicación repetidamente cada vez que actualiza una consulta de búsqueda o selección (finder o select).

El uso de la API de consulta dinámica es un bean de sesión sin estado parecido al uso de cualquier otro bean de aplicación EJB de J2EE. Se incluye en com.ibm.websphere.ejbquery en el paquete de la API.

El bean de consulta dinámica tiene una interfaz remota y otra local. Si se prefiere devolver las referencias EJB remotas de una consulta o si la sentencia de la consulta contiene métodos remotos, se debe utilizar la interfaz remota de consulta:

remote interface = com.ibm.websphere.ejbquery.Query
remote home interface = com.ibm.websphere.ejbquery.QueryHome

Si se prefiere devolver las referencias EJB locales de una consulta o si la sentencia de la consulta contiene métodos locales, se debe utilizar la interfaz local de consulta:

local interface = com.ibm.websphere.ejbquery.QueryLocal
local home interface = com.ibm.websphere.ejbquery.QueryLocalHome

Dado que utiliza menos memoria del servidor de aplicaciones, la interfaz local asegura un rendimiento global EJB mejor que la interfaz remota.

Procedimiento

  1. Verifique que el archivo de aplicación query.ear esté instalado en el servidor de aplicaciones en el que va a ejecutarse la aplicación, si este servidor no es el servidor de aplicaciones predeterminado creado durante la instalación del producto.
    El archivo query.ear está situado en el directorio raíz_servidor_aplicaciones, donde <WAS_HOME> es la ubicación de WebSphere Application Server. El programa de instalación de producto instala el archivo query.ear en el servidor de aplicaciones predeterminado utilizando un nombre JNDI de
    com/ibm/websphere/ejbquery/Query
    (usted o el administrador del sistema pueden cambiar este nombre).
  2. Configure la autorización para los métodos executeQuery(), prepareQuery() y executePlan() en las interfaces de consulta dinámica remota y local para controlar el acceso a datos importantes (este paso sólo es necesario si la aplicación requiere seguridad).

    Dado que no puede controlar qué nombres ASN, campos CMP o campos CMR pueden utilizarse en una consulta dinámica EJB, usted o el administrador del sistema deben establecer restricciones en la utilización de los métodos. Si, por ejemplo, un usuario tiene permiso para ejecutar el método executeQuery, este usuario puede ejecutar cualquier consulta dinámica válida. En un entorno de producción, es deseable restringir el acceso a los métodos de la interfaz de consulta remota.

  3. Escriba la consulta dinámica como parte del código cliente de aplicaciones. Puede consultar los ejemplos siguientes como modelos de consulta: ejemplo de consulta dinámica de interfaz remota y ejemplo de consulta dinámica de interfaz local; muestran qué sentencias de importación deben utilizarse.
  4. Si la CMP que desea consultar está en un módulo diferente, debe:
    1. realizar una búsqueda remota en query.ear
    2. correlacionar el archivo query.ear con el servidor en el que está instalado el bean CMP consultado.
  5. Compile y ejecute su programa cliente con el archivo qryclient.jar en la classpath.

Ejemplo

Utilización de la interfaz remota para la consulta dinámica.

Al ejecutar una consulta dinámica EJB (Enterprise JavaBeans) mediante la interfaz remota, se llama al método executeQuery de la interfaz Query. El método executeQuery tiene un atributo de transacción de REQUIRED para esta interfaz; por tanto, no es necesario establecer explícitamente un contexto de transacción para poder ejecutar la consulta.

Al ejecutar una consulta dinámica EJB (Enterprise JavaBeans) mediante la interfaz remota, se llama al método executeQuery de la interfaz Query. El método executeQuery tiene un atributo de transacción de REQUIRED para esta interfaz; por tanto, no es necesario establecer explícitamente un contexto de transacción para poder ejecutar la consulta.

Empiece con las sentencias de importación siguientes:

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;

A continuación, escriba la sentencia de consulta como una serie, como en el ejemplo siguiente que recupera los nombres y las referencias EJB para empleados con un sueldo bajo:

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

Cree un objeto Query obteniendo una referencia de la clase QueryHome (esta clase define el método executeQuery method). Tenga en cuenta que por motivos de simplicidad, en el ejemplo siguiente se utiliza el nombre JNDI de la consulta dinámica para el 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();

A continuación, especifique un tamaño máximo para el conjunto de resultados de la consulta, que se define en el objeto QueryIterator. A continuación, debe especificar un tamaño máximo para el conjunto de resultados de la consulta, que se define en el objeto QueryIterator que se incluye en el paquete de la API QueryIterator. Este ejemplo establece el tamaño máximo del conjunto de resultados en 99:

QueryIterator it = qb.executeQuery(query, null, null ,0, 99 );
El iterador contiene una colección de objetos IQueryTuple, que son registros de los valores de recopilación devueltos Según los criterios de la sentencia de consulta del ejemplo, cada tupla de este caso práctico contiene un valor name y un valor object(e). Para visualizar el contenido del resultado de esta consulta, utilice el código siguiente:
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());
}
La salida del programa puede ser similar a la siguiente:
name Bob 
emp 1001
name Dave
emp 298003
...
Finalmente, capture y procese las excepciones. Es posible que se genere una excepción si se produce un error de sintaxis en la sentencia de la consulta o un error de proceso durante la ejecución. El ejemplo siguiente captura y procesa estas excepciones:
} catch (QueryException qe) {
    System.out.println("Query Exception "+ qe.getMessage() );
}

Manejo de colecciones de resultados de gran tamaño para la consulta de interfaz remota

Si quiere que la consulta devuelva una gran recopilación de resultados, tiene la opción de programarla para que devuelva resultados en múltiplos más pequeños, en cantidades más manejables. Utilice los parámetros skipRow y maxRow en el método remoto executeQuery para recuperar la respuesta en chunks. Por ejemplo:

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() ) ;
Utilización de la interfaz local para la consulta dinámica.

Al ejecutar una consulta dinámica EJB (Enterprise JavaBeans) mediante la interfaz local, se llama al método executeQuery de la interfaz QueryLocal. Esta interfaz no inicia una transacción para el método; por tanto, debe establecer explícitamente un contexto de transacción para poder ejecutar la consulta.

Nota: Para establecer un contexto de transacción, el ejemplo siguiente llama a los métodos begin() y commit(). Como alternativa a la utilización de estos métodos, puede incorporar el código de consulta en un método EJB que se ejecute en un contexto de transacción.

Inicie el código de consulta con las sentencias de importación siguientes:

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;

A continuación, escriba la sentencia de consulta como una serie, como en el ejemplo siguiente que recupera los nombres y las referencias EJB para empleados con un sueldo bajo:

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

Cree un objeto QueryLocal obteniendo una referencia de la clase QueryLocalHome (esta clase define el método executeQuery method). Tenga en cuenta que en el ejemplo siguiente, ejb/query se utiliza como referencia local EJB que apunta al nombre JNDI de la 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();

La última porción de código inicia una transacción, llama al método executeQuery y visualiza los resultados de la consulta. Se crea una instancia de la clase QueryLocalIterator porque define el conjunto de resultados de la consulta Esta clase se incluye en el paquete de la API en la clase QueryIterator. Recuerde que el iterador pierde validez al final de la transacción; debe utilizar el iterador en el mismo ámbito de transacción que la llamada 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();

En la mayoría de las situaciones, el objeto QueryLocalIterator es gestionado por demanda. Es decir, provoca que los datos se devuelvan en incrementos: para cada recuperación de registro de la base de datos, debe llamarse al método next() en el iterador (pueden existir situaciones en las que el iterador no sea gestionado por demanda. Si desea más información, consulte la subsección Interfaces de consulta local del tema Consideraciones de rendimiento de consulta dinámica.)

Dado que la totalidad del conjunto de resultados de la consulta se materializa en incrementos en la memoria del servidor de aplicaciones, puede controlar su tamaño fácilmente. Durante una ejecución de prueba, por ejemplo, puede decidir que sólo se devuelvan unas cuantas tuplas del conjunto de resultados si es necesario. En ese caso, debe utilizar una llamada del método close() en el objeto QueryLocalIterator para cerrar el bucle de la consulta. De este modo se liberan recursos SQL utilizados por el iterador. De lo contrario, estos recursos no se liberan hasta que la totalidad del conjunto de resultados se acumula en la memoria o cuando termina la transacción.


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=tque_dynamic
File name: tque_dynamic.html