Consultas por Criterios
Acompaña a Hibernate una API de consultas por criterios intuitiva y extensible.
Creando una instancia de Criteria
La interface org.hibernate.Criteria representa una consulta contra
una clase persistente en particular. La Session es una fábrica de instancias
de Criteria.
Estrechando el conjunto resultado
Un criterio individual de consulta es una instancia de la interface
org.hibernate.criterion.Criterion. La clase
org.hibernate.criterion.Restrictions define métodos de fábrica para obtener ciertos tipos
prefabricados de Criterion.
Las restricciones pueden ser agrupadas lógicamente.
Hay un gran rango de tipos de criterio prefabricados (subclases de Restrictions),
pero uno que es especialmente útil te deja especificar SQL directamente.
El sitio {alias} será remplazado por el alias de fila de la entidad consultada.
Un enfoque alternativo para obtener un criterio es tomarlo de una instancia de
Property. Puedes crear una Property llamando a
Property.forName().
Ordenando los resultados
Puedes ordenar los resultados usando org.hibernate.criterion.Order.
Asociaciones
Puedes especificar fácilmente restricciones sobre las entidades relacionadas al navegar asociaciones
usando createCriteria().
nota que el segundo createCriteria() devuelve una nueva instancia de
Criteria, que hace referencia a los elementos de la colección
kittens.
La siguiente forma alternativa es útil en ciertas circunstancias.
(createAlias() no crea una nueva instancia de
Criteria.)
¡Observa que las colecciones de gatitos tenidas por las instancias de Cat devueltas
por las dos consultas previas no están prefiltradas por los criterios! Si deseas
recuperar sólo los gatitos que emparejen los criterios, debes usar returnMaps().
Recuperación dinámica de asociaciones
Puedes especificar la semántica de recuperación de asociaciones en tiempo de ejecución usando
setFetchMode().
Esta consulta recuperará tanto mate como kittens por
unión exterior (outer join). Ver para más información.
Consultas por ejemplos
La clase org.hibernate.criterion.Example te permite construir un criterio de consulta
a partir de una instancia dada.
Las propiedades de versión, los identificadores y las asociaciones son ignorados. Por defecto,
las propiedades valuadas a nulo son excluídas.
Puedes ajustar cómo se aplica el Example.
Puedes incluso usar ejemplos para colocar criterios sobre objetos asociados.
Proyecciones, agregación y agrupamiento
La clase org.hibernate.criterion.Projections es una fábrica de instancias de
Projection. Aplicamos una proyección a una consulta llamando a
setProjection().
No es necesario ningún "group by" explícito en una consulta por criterios.
Ciertos tipos de proyecciones son definidos para ser proyecciones agrupadas,
que además aparecen en la cláusula SQL group by.
Puede opcionalmente asignarse un alias a una proyección, de modo que el valor proyectado pueda
ser referido en restricciones u ordenamientos. Aquí hay dos formas diferentes de hacer esto:
Los métodos alias() y as() simplemente envuelven una instancia
de proyección en otra instancia de Projection con alias. Como un atajo, puedes asignar
un alias cuando agregas la proyección a una lista de proyecciones:
Puedes también usar Property.forName() para expresar proyecciones:
Consultas y subconsultas separadas
La clase DetachedCriteria te deja crear una consulta fuera del ámbito de una sesión,
y entonces ejecutarla luego usando alguna Session arbitraria.
También una DetachedCriteria puede usarse para expresar una subconsulta.
Las instancias de Criterion implicando subconsultas pueden obtenerse vía Subqueries o
Property.
Incluso son posibles las subconsultas correlacionadas:
Consultas por identificador natural
Para la mayoría de consultas, incluyendo las consultas por criterios, el caché de consulta no es
muy eficiente, debido a que la invalidación del caché de consulta ocurre demasiado frecuentemente.
Sin embargo, hay un tipo especial de consulta donde podemos optimizar el algoritmo de invalidación
de caché: búsquedas por una clave natural constante. En algunas aplicaciones, este tipo de consulta,
ocurre frecuentemente. La API de criterios brinda especial provisión para este caso de uso.
Primero, debes mapear la clave natural de tu entidad usando
<natural-id>, y habilitar el uso del caché de segundo nivel.
]]>
Nota que esta funcionalidad no está pensada para uso con entidades con claves naturales
mutable.
Seguido, habilita el caché de consulta de Hibernate.
Ahora, Restrictions.naturalId() nos permite hacer uso de el algoritmo de caché
más eficiente.