Herramientas de usuario

Herramientas del sitio


unidades:05_hibernate_query_language:04_colecciones

Diferencias

Muestra las diferencias entre dos versiones de la página.


unidades:05_hibernate_query_language:04_colecciones [2023/04/07 21:26] (actual) – creado - editor externo 127.0.0.1
Línea 1: Línea 1:
 +====== Objetos y colecciones ======
 +En este tema volvemos  a ver mas características del Hibernate Query Languaje (HQL).
  
 +Hasta ahora el HQL es un lenguaje de consultas muy similar a SQL sólo que usando como modelo de datos subyacente clases Java en vez de Tablas SQL. Sin embargo,  el hecho de usar clases Java le hace tener características que no existen en SQL ((al menos en el SQL Estándar)) al estar éste último basado en Tablas. 
 +
 +===== Modelo =====
 +En los ejemplos que vamos a realizar van a usarse las siguientes clases Java y tablas, que sólo mostraremos en formato UML. No vamos a poner el código fuente ni los ficheros de hibernate de mapeo ya que no todas la características que usan han sido explicadas en lecciones anteriores.
 +
 +==== Modelo de Java ====
 +El modelo de clases Java es el siguiente:
 +
 +<uml>
 +class Profesor 
 +Profesor : int id
 +
 +class Nombre
 +Nombre : String nombre
 +Nombre : String ape1
 +Nombre : String ape2
 +
 +class Direccion
 +Direccion : int id
 +Direccion : String calle
 +Direccion : int numero
 +Direccion : String provincia
 +
 +class Municipio
 +Municipio : int idMunicipio
 +Municipio : String codProvincia
 +Municipio : String codMunicipio
 +Municipio : String nombre
 +
 +class CorreoElectronico
 +CorreoElectronico: int idCorreo
 +CorreoElectronico: String direccionCorreo
 +
 +
 +Profesor "1" -- "0..n" CorreoElectronico: correosElectronicos
 +Profesor "1" -- "1" Nombre : nombre
 +Profesor "1" -- "1" Direccion : direccion
 +Direccion "*" -- "1" Municipio : municipio
 +</uml>
 +==== Modelo de Tablas ====
 +El modelo de tablas es el siguiente:
 +
 +<uml>
 +class Profesor <<Table>>
 +Profesor : INTEGER id
 +Profesor : VARCHAR nombre
 +Profesor : VARCHAR ape1
 +Profesor : VARCHAR ape2
 +
 +
 +class CorreoElectronico <<Table>>
 +CorreoElectronico: INTEGER idCorreo
 +CorreoElectronico: VARCHAR direccionCorreo
 +CorreoElectronico: INTEGER idProfesor
 +
 +class Direccion <<Table>>
 +Direccion : INTEGER id
 +Direccion : VARCHAR calle
 +Direccion : INTEGER numero
 +Direccion : VARCHAR IdMunicipio
 +Direccion : VARCHAR provincia
 +
 +class Municipio <<Table>>
 +Municipio : INTEGER idMunicipio
 +Municipio : VARCHAR codProvincia
 +Municipio : VARCHAR codMunicipio
 +Municipio : VARCHAR nombre
 +
 +Profesor "1" -- "0..n" CorreoElectronico
 +Profesor "1" -- "1" Direccion 
 +Direccion "*" -- "1" Municipio 
 +</uml>
 +
 +=====  =====
 +
 +
 +Las características especificas de HQL por usar como modelo clases Java son:
 +  * [[#Navegación por propiedades]]
 +  * [[#Colecciones]]
 +
 +==== Navegación por propiedades ====
 +Una característica de HQL es la posibilidad de navegar por las propiedades.
 +
 +En HQL si referenciamos una propiedad de un clase Java , esta propiedad puede no ser un valor escalar sino una referencia a otro objeto Java, que a su vez tiene más propiedades, lo que a su vez nos puede llevas hasta otro objeto Java y así sucesivamente. Es decir, podemos acceder a propiedades de Clases que no están en la cláusula ''FROM'' pero accedemos a ellas desde la clase inicial de la consulta.
 +
 +Por ejemplo:
 +<code sql>
 +SELECT p.nombre.ape1 FROM Profesor p
 +</code>
 +
 +Aquí vemos cómo desde objeto ''Profesor'' se //navega// mediante la propiedad ''nombre'' a la clase ''Nombre'' y de ahí a su propiedad ''ape1''.
 +
 +Los mismo se puede hacer con el nombre del municipio.
 +<code sql|Mostrar el Id y el municipio de cada profesor>
 +SELECT p.nombre.ape1,p.direccion.municipio.nombre FROM Profesor p
 +</code>
 +Desde la clase ''Profesor'' se navega hacia la clase ''Direccion'' mediante la propiedad ''direccion'' y desde ésta al ''Municipio'' mediante la propiedad ''municipio'' donde finalmente se accede a la propiedad ''nombre'' de la clase''Municipio'' .
 +
 +Realmente esta característica es la misma que hacemos desde Java usando los métodos ''get'' de cada clase Java y encadenando las llamadas. En código Java la navegación anterior quedaría de la siguiente forma:
 +
 +<code java>
 +Profesor profesor=......;
 +        
 +String nombreMunicipio=profesor.getDireccion().getMunicipio().getNombre();
 +</code>
 +
 +Así que no debe extrañarnos que podamos realizarlo desde HQL.
 +
 +<note tip>
 +Si comprobamos la SQL que lanza Hibernate , podemos comprobar que lanza una SELECT en la que realiza todos los ''JOINS'' necesarios para acceder a todas las tablas que realmente necesita, pero desde nuestro punto de vista sólo navegamos por propiedades Java.
 +
 +Así que esta característica de Hibernate es muy útil y potente.
 +
 +<code sql>
 +SELECT 
 + profesor0_.ape1 AS col_0_0_, 
 + municipio2_.NombreMunicipio AS col_1_0_
 +FROM 
 + Profesor profesor0_, 
 + Direccion direccion1_, 
 + Municipios municipio2_
 +WHERE 
 + profesor0_.Id=direccion1_.Id AND 
 + direccion1_.idMunicipio=municipio2_.idMunicipio
 +</code>
 +</note>
 +==== Colecciones ====
 +Otra característica de HQL es la posibilidad de tratar con colecciones dentro de la propia consulta. Veamos las funciones que tratan con colecciones.
 +
 +  
 +
 +  * ''SIZE(c)'': Obtiene el nº de elementos de una colección.<code sql|Para cada municipio obtiene el nº de reparaciones>
 +SELECT p.nombre.ape1,SIZE(p.correosElectronicos) FROM Profesor p Group by p.nombre.ape1
 +</code>
 +  * ''c IS EMPTY'': Comprueba si una colección **no** tiene elementos.<code sql|Muestra los municipios sin reparaciones>
 +SELECT p.nombre FROM Profesor p WHERE p.correosElectronicos IS EMPTY
 +</code>
 +  * ''IS NOT EMPTY c'': Comprueba si una colección **sí** tiene elementos.<code sql|Muestra los municipios con reparaciones>
 +SELECT p.nombre FROM Profesor p WHERE p.correosElectronicos IS NOT EMPTY
 +</code>
 +  * ''MINELEMENT(c)'': Retorna el menor de los elementos de la colección. Para averiguar cual es el menor siempre usa el campo que hace de ''id''.
 +  * ''MAXELEMENT(c)'': Retorna el mayor de los elementos de la colección. Para averiguar cual es el mayor siempre usa el campo que hace de ''id''.