====== Consultas en beans de entidad ======
--- //[[pedrody@um.es|PEDRO DELGADO YARZA]] 2014/02/06 08:53//
A la hora de desarrollar aplicaciones, surge la necesidad de realizar consultas a base de datos para recuperar objetos basados en diversos criterios. Dichas consultas en el pasado se han basado netamente en ejecutar consultas nativas SQL de base de datos y mapeando manualmente a clases java, a posteriori, dichos resultados.
Actualmente, el motor de persistencia nos provee de una manera algo más cómoda de recuperar esos datos, ahorrándonos el mapeo manual de valores y simplificando la manera de realizar las [[http://docs.jboss.org/hibernate/core/4.2/manual/en-US/html/ch16.html|consultas JPQL]] o consultas nativas SQL. No obstante se nos permite seguir realizando dichas búsquedas de la manera anterior, este hecho hace que distingamos entre dos tipos de consultas:
* **NamedQuery**: Consultas escritas en el lenguaje proporcionado por el motor de persistencia, en el caso de Hibernate el HQL.
* **NamedNativeQuery**: Consultas escritas en lenguaje SQL nativo.
Utilizando cualquiera de los tipos anteriores podemos lanzar nuestras consultas a base de datos, no obstante la configuración necesaria para cada una difiere, como veremos en apartados sucesivos.
=====Definición de Queries=====
Una vez que queremos empezar a preparar consultas de base de datos debemos decidir dónde definirlas. En este punto existen dos puntos básicos donde eñnglobarlas:
* **Consultas declaradas dentro de un bean de entidad**: Estas consultas se declaran en la propia clase del bean de entidad y tienen como requisito que los objetos que devuelva sean del tipo del bean.
* **Consultas declaradas en el fichero orm.xml**: Estas consultas se declaran en un fichero de configuración **orm.xml** y pueden devolver o no beans de entidad. En este caso no se aplica ninguna restrucción concreta.
**Consultas declaradas dentro de un bean de entidad**
Están contenidas dentro de la clase del bean al que representan y escritas en código HQL. Se disponen en la cabecera de la clase dentro de la anotación **@NamedQueries** o **NamedNativeQueries**, indicando cada query con la anotación **@NamedQuery** o **@NamedNativeQuery** según si queremos escribirlas en HQL o SLQ.
Un ejemplo con HQL sería:
@Entity
@NamedQueries({
@NamedQuery(name = "anuncioFiltrado", query = "select an from Anuncio an where an.id like :id and lower(an.descripcion) like :descripcion and lower(an.nombre) like :nombre and ((:fechaPublicacion is null) OR (an.fechaPublicacion=:fechaPublicacion))"),
@NamedQuery(name = "totalAnuncioFiltrado", query = "select count(an) from Anuncio an where an.id like :id and lower(an.descripcion) like :descripcion and lower(an.nombre) like :nombre and ((:fechaPublicacion is null) OR (an.fechaPublicacion=:fechaPublicacion))") })
public class Anuncio implements Serializable {
...
...
}
Como podemos ver, necesitamos hacer uso de dos anotaciones:
* **NamedQueries**: Especifica una lista separada por comas de consultas HQL.
* **NamedQuery**: Representa una consulta HQL. Sus propiedades son:
* **name**: Nombre de la consulta. Este nombre lo utilizaremos a la hora de buscarla para lanzarla.
* **query**: Consulta en HQL.
* **hints**: Propiedades adicionales que queramos darle a la consulta.
De igual manera, si quisiéramos especificarlas en SQL:
@NamedNativeQueries( {
@NamedNativeQuery(name = "consultaAnunciosNativa", query = "SELECT * FROM ANUNCIO", resultClass=Anuncio.class)
})
Al igual que antes necesitamos hacer uso de dos anotaciones:
* **NamedNativeQueries**: Especifica una lista separada por comas de consultas SQL.
* **NamedNativeQuery**: Representa una consulta SQL. Sus propiedades son:
* **name**: Nombre de la consulta. Este nombre lo utilizaremos a la hora de buscarla para lanzarla.
* **query**: Consulta en SQL.
* **resultClass**: Clase a la que se ha de mapear el resultado de la consulta.
**Consultas declaradas en el fichero orm.xml**
Las consultas anteriores, pueden realizarse registrarse en vez de en el propio bean, en el fichero de configuración orm.xml mediante tags xml.
En el caso de las consultas HQL haremos uso del tag **named-query**
select anuncio from Anuncio anuncio
Como vemos, las propiedades que requiere son las mismas que son necesarias en el caso anterior, teniendo en el tag **** la consulta, y en la lista de tags **** las propiedades adicionales.
En el caso de que quisiéramos hacer la consulta en SLQ nativo, usaríamos el tag **named-native-query** procediendo de la siguiente manera:
SELECT * FROM ANUNCIO
Las propiedades adicionales siguen el mismo esquema que el caso anterior.
=====Consultas que no devuelven todos los campos de un Bean de Entidad=====
Si queremos realizar una consulta que sólo devuelva un subconjunto de los campos de una tabla, o que devuelva campos de tablas distintas debemos realizar las consultas de dos posibles maneras:
* Escribir una named-query que devuelva sólo los campos que queremos. El resultado de esta consulta devolverá un **ArrayList