Desarrollo de aplicaciones que utilizan consultas EJB

La empresa JavaBeans (EJB) se utiliza para especificar una consulta sobre beans de entidad administrados por contenedor. El lenguaje es como un lenguaje de consulta estructurado (SQL o Structured Query Language). Las consultas EJB son independientes de la correlación del bean con un almacén persistente.

Acerca de esta tarea

Se pueden utilizar las consultas EJB en tres situaciones:
  • Para definir un método finder de un bean de entidad EJB.
  • Para definir un método select de un bean de entidad EJB.
  • Para especificar dinámicamente una consulta con la API dinámica de método executeQuery().
Las consultas de búsqueda y selección se especifican en el descriptor de implementación del bean usando el<ejb-ql>etiqueta; se compilan en SQL durante la implementación. Las consultas dinámicas se incluyen con el propio código de la aplicación.

El lenguaje de consulta EJB del producto es compatible con el QL de EJB definido en Sun EJB. 2.1, EJB 3.0 y EJB 3.1 especificaciones y tiene capacidades adicionales como se enumeran en el tema Comparación de la especificación EJB y WebSphere® Lenguaje de consulta.

Procedimiento

  • Antes de utilizar una consulta EJB, familiarícese con conceptos del lenguaje de consultas, empezando por el tema Lenguaje de consulta EJB.
  • Defina una consulta EJB de uno de los modos siguientes:
    • Rational® Application Developer. Al definir un bean de entidad, especifique el<ejb-ql>etiqueta para el buscador o método de selección. Para obtener más información sobre el uso Rational Application Developer consulte la documentación de la herramienta de montaje.
    • Servicio de consulta dinámica. Añada el método executeQuery a la aplicación.

Ejemplo: consultas con EJB

Aquí hay un ejemplo de empresa. JavaBeans (EJB), seguido de un conjunto de consultas de ejemplo.

Tabla 1. Esquema EJB y consultas de ejemplo . Esquema EJB y consultas de ejemplo
Esquema EJB Consulta de ejemplo
Nombre de bean de entidad (nombre de EJB) DeptEJB (no se utiliza en la consulta)
Nombre de esquema abstracto DeptBean
Clase de implementación com.acme.hr.deptBean (no se utiliza en la consulta)
Atributos persistentes (campos cmp)
  • deptno - Integer (key)
  • name - Serie
  • budget - BigDecimal
Relaciones
  • emps - 1:Many with EmpEJB
  • mgr - Many:1 with EmpEJB
Tabla 2. Esquema EJB y consultas de ejemplo . Esquema EJB y consultas de ejemplo
Esquema EJB Consulta de ejemplo
Nombre de bean de entidad (nombre de EJB) EmpEJB (no se utiliza en la consulta)
Nombre de esquema abstracto EmpBean
Clase de implementación com.acme.hr.empBean (no se utiliza en la consulta)
Atributos persistentes (campos cmp)
  • empid - entero (clave)
  • name - Serie
  • salary - BigDecimal
  • bonus - BigDecimal
  • hireDate - java.sql.Date
  • birthDate - java.util.Calendar
  • address - com.acme.hr.Address
Relaciones
  • dept - Many:1 with DeptEJB
  • manages - 1:Many with DeptEJB
La dirección es un objeto serializable que se utiliza como campo cmp en EmpBean. La definición de la dirección es la siguiente:
    public class com.acme.hr.Address  extends Object implements Serializable { 
	public String street;
	public String state;
	public String city;
	public Integer zip;
      public double distance (String start_location) { ... } ;
      public  String format ( ) { ... } ;
 }
La consulta siguiente devuelve todos los departamentos:
SELECT OBJECT(d) FROM DeptBean d
La consulta siguiente devuelve los departamentos cuyo nombre comienza por las letras "Web". Clasifique el resultado por nombre:
SELECT OBJECT(d) FROM DeptBean d WHERE  d.name LIKE  'Web%' ORDER BY d.name
Las palabras clave SELECT y FROM se muestran en mayúsculas en los ejemplos, pero no son sensibles a mayúsculas y minúsculas. Si un nombre utilizado en una consulta es una palabra reservada, el nombre debe especificarse entre comillas dobles para su utilización en la consulta. Puede encontrar una lista de palabras reservadas en Consulta EJB: palabras reservadas. Los identificadores que aparecen entre comillas dobles son sensibles a mayúsculas y minúsculas. Este ejemplo le muestra cómo utilizar un campo cmp que es una palabra reservada:
SELECT OBJECT(d) FROM DeptBean d  WHERE  d."select" > 5
La consulta siguiente devuelve todos los ejemplos que están bajo la supervisión de Bob. Este ejemplo muestra cómo navegar por las relaciones utilizando una expresión path:
SELECT OBJECT (e) FROM EmpBean e WHERE e.dept.mgr.name='Bob'
Una consulta puede contener un parámetro que haga referencia al valor correspondiente del método finder o select. Los parámetros de consulta se numeran comenzando por 1:
SELECT OBJECT (e) FROM EmpBean e WHERE e.dept.mgr.name= ?1
Esta consulta muestra cómo se navega por una relación de varios valores y devuelve todos los departamentos que tienen un empleado que gana como mínimo 50000 pero no más de 90000:
SELECT OBJECT(d) FROM DeptBean d,  IN (d.emps) AS e
WHERE e.salary BETWEEN 50000 and 90000

Hay una operación conjunta implícita en esta consulta entre cada objeto de departamento y su agrupación de empleados relacionados. Si un departamento no tiene empleados, el departamento no aparecerá en el resultado. Si un departamento tiene más de un empleado que gana más de 50000, este departamento aparecerá varias veces en el resultado.

La consulta siguiente elimina los departamentos duplicados:
SELECT DISTINCT OBJECT(d) from DeptBean d,  IN (d.emps) AS e  WHERE e.salary > 50000
Buscar empleados cuyas bonificaciones sean superiores al 40% de su sueldo:
SELECT OBJECT(e) FROM EmpBean e where e.bonus > 0.40 * e.salary
Buscar departamentos en los que la suma del sueldo y las bonificaciones de los empleados del departamento supere el presupuesto del departamento:
SELECT OBJECT(d) FROM DeptBean d where d.budget < 
( SELECT SUM(e.salary+e.bonus) FROM IN(d.emps) AS e )
Una consulta puede contener DB2® estilo expresiones aritméticas de fecha y hora si usa java.sql.* tipos de datos como campos CMP y su almacén de datos es DB2. Buscar todos los empleados que han trabajado como mínimo 20 años desde el 1 de Enero de 2000:
SELECT OBJECT(e) FROM EmpBean e where year(  '2000-01-01' - e.hireDate ) >= 20
Si el almacén de datos no es DB2 o si prefieres usar java.util.Calendar como campo CMP, puede utilizar el valor de milisegundos de Java en las consultas. La consulta siguiente busca todos los empleados nacidos antes del 1 de Enero de 1990:
SELECT OBJECT(e) FROM EmpBean e WHERE e.birthDate <  631180800232
Buscar departamentos sin empleados:
SELECT OBJECT(d) from DeptBean d where d.emps IS EMPTY
Buscar todos los empleados que ganan más que Bob:
SELECT OBJECT(e) FROM EmpBean e, EmpBean b
WHERE b.name = 'Bob' AND e.salary + e.bonus > b.salary + b.bonus
Buscar el empleado con la bonificación más elevada:
SELECT OBJECT(e) from EmpBean e  WHERE e.bonus =
(SELECT MAX(e1.bonus) from EmpBean e1)

Las consultas indicadas anteriormente devuelven todas objetos EJB. Un método finder siempre debe devolver un objeto EJB como inicio. Una consulta de método select puede además devolver campos CMP u otros objeto EJB que no pertenecen al inicio.

Las siguientes pueden ser consultas del método select válidas para EmpBean. Devolver el jefe de cada departamento:
SELECT  d.mgr FROM DeptBean d
Devolver el nombre del jefe del departamento 42:
SELECT  d.mgr.name FROM DeptBean d WHERE  d.deptno = 42
Devolver los nombres de los empleados del departamento 42:
SELECT e.name FROM EmpBean e WHERE  e.dept.deptno=42
Otro modo de escribir la misma consulta es:
SELECT e.name from DeptBean d, IN (d.emps) AS e WHERE d.deptno=42
Las consultas de los métodos finder y select solamente permiten un campo CMP o EJBObject en la cláusula SELECT. Una consulta de selección puede devolver valores agregados en Enterprise JavaBeans 2.1 usando SUMA, MIN, MAX, AVG y COUNT.
SELECT max(e.salary) FROM EmpBean e WHERE e.dept.deptno=42
La API de consultas dinámicas permite varias expresiones en la cláusula SELECT. La consulta siguiente sería una consulta dinámica válida pero no una consulta select o finder válida:
SELECT  e.name, e.salary+e.bonus as total_pay , object(e), e.dept.mgr
FROM  EmpBean e
ORDER BY 2
La siguiente consulta dinámica devuelve el número de empleados de cada departamento:
SELECT e.dept.deptno as department_number , count(*) as employee_count
FROM  EmpBean e
GROUP BY  by e.dept.deptno
ORDER BY 1
La API de consultas dinámicas permite consultas que contienen métodos de objeto de valor o de bean:
SELECT object(e), e.address.format( )
FROM EmpBean e EmpBean e