170 likes | 391 Views
HQL. Lenguaje de consulta de Hibernate. Recuperación de datos. La recuperación de los datos persistidos puede realizarse: Directamente mediante el objeto Session. Generando un objeto Criteria. Utilizando la api correspondiente. Generando un objeto Query: Utilizando el lenguaje hql.
E N D
HQL Lenguaje de consulta de Hibernate Aplicaciones Distribuidas
Recuperación de datos • La recuperación de los datos persistidos puede realizarse: • Directamente mediante el objeto Session. • Generando un objeto Criteria. • Utilizando la api correspondiente. • Generando un objeto Query: • Utilizando el lenguaje hql. • Utilizando el lenguaje sql nativo. 2011 Aplicaciones Distribuidas
Load() • Los métodos load() de Session proporcionan una forma de recuperar una instancia persistente si ya se conoce su identificador. load() toma un objeto clase y carga el estado dentro de un objeto recién instanciado de esa clase, en un estado persistente. Usuario usuario = new Usuario(); usuario.setCuit(cuit); … session.load(usuario, usuario.getCuit()); session.close(); Obtiene al usuario por su clave primaria. Otra forma es recuperar al objeto mediante el valor escalar de la PK: Usuario usu = (Usuario) session.load(Usuario.class, cuit); El método load() lanzará una excepción irrecuperable si no hay una fila correspondiente en la base de datos. Si no hay certeza de que existe una fila correspondiente, se debe utilizar el método get(), que devuelve nulo si no existe una fila correspondiente. Usuario usu = (Usuario) session.get(Usuario.class, cuit); 2011 Aplicaciones Distribuidas
Interfaz Query • Si no se conocen los identificadores de los objetos que se están buscando, se necesita una consulta. Se representa en una instancia de org.hibernate.Query. Esta interfaz ofrece métodos para ligar parámetros, manejo del conjunto resultado, y para la ejecución de la consulta real. • Un Objeto Query se crea desde el objeto Session: Query query = session.createQuery( String ); • El método list() del objeto Query retorna una colección del tipo List de los objetos recuperados de la base. Query query = session.createQuery(“from Persona” ); List<Persona> list = query.list(); El argumento ‘from Persona’ representaría a la consulta sql ‘ select * from personas’ . La interfaz Query se encarga de ejecutarla y recuperar el ResultSet asociado, retornando un ArrayList de objetos tipo Persona mapeados con la tabla ‘personas’. 2011 Aplicaciones Distribuidas
Interfaz Query • Una consulta se ejecuta usualmente invocando a list(). El resultado de la consulta será cargado completamente dentro de una colección en memoria. Las instancias de entidad recuperadas por una consulta se encuentran en estado persistente. • Las consultas HQL y SQL nativas son representadas con una instancia de org.hibernate.Query. List<Usuario> list = session.createQuery(“from Usuario ").list(); • Si las consultas devuelven muchas filas puede paginarse la cantidad devuelta. Query q = session.createQuery("from Usuario "); q.setFirstResult( desde ); q.setMaxResults( cantidadMaxima ); List<Usuario> list = q.list(); 2011 Aplicaciones Distribuidas
iterate() • La colección del tipo List que retornaría de un objeto Query, puede en algunos casos ser iterada para mayor control o selección sobre los datos recuperados. • Se puede ejecutar la consulta con el método iterate(), que devuelve el iterador de la lista. Iterator ilista = session.createQuery( "select U, T from Usuario U join U.telefonos T") .iterate(); Set<Usuario> set = new HashSet<Usuario>(); while(ilista.hasNext()) { Object[] tupla = (Object[]) ilista.next(); Usuario u = (Usuario) tupla[0]; set.add(u); } 2011 Aplicaciones Distribuidas
uniqueResult() • Cuando una consulta retorna un único resultado (sea un escalar o un objeto) no sería práctico retornarla en una interfaz List o recuperarla mediante Iterator. • Si se conoce que devuelve un solo objeto se debiera utilizar el método uniqueResult(). Query q = session.createQuery("from Usuario "); q.setFirstResult( desde ); q.setMaxResults( 1 ); Usuario usuario = q.uniqueResult(); o tambien: Usuario usuario = session.createQuery("from Usuario ") .setFirstResult( desde ) .setMaxResults( 1 ); .uniqueResult(); 2011 Aplicaciones Distribuidas
HQL • Hibernate soporta un lenguaje de consulta orientado a objetos (HQL). Estructuralmente similar a SQL, con la gran diferencia que se referencian objetos y propiedades de éstos y no tablas y columnas como en el lenguaje sql. • Las consultas HQL son representadas con una instancia de Query. • Presenta distintas cláusulas que permiten definir una consulta: • Select • From • Where • Group by • Having • Order by 2011 Aplicaciones Distribuidas
Cláusula from • Cláusula donde se indica explícitamente los objetos que serán recuperados por medio de la consulta: // Retorna todas las instancias de la clase Usuario Query q = session.createQuery("from Usuario"); // Para referirse en otras partes de la consulta, se necesita asignar un alias. Query q = session.createQuery("from Cuenta cta"); // Pueden aparecer múltiples clases, lo que causa un producto cartesiano o una unión cruzada (cross join). Query q = session.createQuery("from Formula f, Parametro p"); 2011 Aplicaciones Distribuidas
Asociaciones y uniones - joins • Se utiliza join para recuperar entidades asociadas o a elementos de una colección de valores. • Pueden ser del tipo: • inner join • outer join • left outer join • right outer join • full outer join • Ejemplos: • from Cuenta cta join cta.usuarios • from Usuario usu join usu.cuentas ctas left join usu.telefonos fonos 2011 Aplicaciones Distribuidas
Cláusula select • La cláusula select determina qué objetos y propiedades devolver en el conjunto de resultados de la consulta: // Retorna los usuarios que poseen teléfono select usu from Usuario usu join usu.telefonos // Retorna las cuentas de los usuarios. select usu.cuentas from Usuario usu join usu.cuentas // Retorna tuplas como arreglos de Object - List<Object[]>. select usu,cuentas from Usuario usu join usu.cuentas cuentas 2011 Aplicaciones Distribuidas
Cláusula where • Condiciona por cualquier valor de las propiedades de los objetos indicados en la cláusula from • from Usuario where nombre = ‘juan’ • from Usuario usu where usu.nombre = ‘juan’ • from Usuario usu where usu.nombre like ’%a%’ • from Usuario usu where usu.domicilio is not null and usu.domicilio.cp in (1000, 1833, 1400) • from Usuario usu, Usuario u where usu.domicilio = u.domicilio • from Usuario usu where usu.nombre between ’A’ and ‘B’ • from Usuario usu where size (usu.cuentas) > 2 and usu.cuit like ’%0’ • from Usuario usu where exists usu.telefonos • from Usuario usu join usu.cuentas ctas where ctas.saldo > 1000 2011 Aplicaciones Distribuidas
parámetros Los objetos Query proporcionan parámetros para enlazar valores en la consulta. Al contrario de JDBC, Hibernate numera los parámetros desde cero. Los parámetros con nombre son identificadores de la forma :name en la cadena de la consulta. Las ventajas de los parámetros con nombre son las siguientes: • los parámetros con nombre son insensibles al orden en que aparecen en la cadena de consulta • pueden aparecer múltiples veces en la misma petición • son auto-documentados Query q = session.createQuery( "select usu.cuentas from Usuario usu where usu.ciut = ?") .setString(0,usuario.getCuit()); Query q = session.createQuery( "select usu.cuentas from Usuario usu where usu.cuit = :cuit") .setString(“cuit”,usuario.getCuit()); Aplicaciones Distribuidas
Lista de parámetros • Los parámetros pueden componer una lista de valores public List<Object[]> consulta (List<String> lstnombres) { Session session = sf.openSession(); List<Object[]> lista = session.createQuery( "select usu, ctas from Usuario usu left join U.cuentas ctas " + "where usu.nombre in(:nombres)") .setParameterList("nombres", lstnombres) .list(); session.close(); return lista; 2011 Aplicaciones Distribuidas
Cláusula group by • Una consulta que retorna valores agregados se puede agrupar por cualquier propiedad de una clase retornada o componentes: • select tel.area, count(tel.numero) from Telefono tel group by tel.area having tel.area <> ‘351’ • select usu.cuit, sum(c.saldo) as saldoTotal from Usuario usu join usu.cuentas c group by usu.cuit order by 2 desc Las funciones SQL y las funciones de agregación SQL están permitidas en las cláusulas having y order by, si están soportadas por la base de datos subyacente. 2011 Aplicaciones Distribuidas
Cláusula order by • Ordena la consulta conforme a una lista de propiedades. • select usu from Usuario usu order by usu.nombre • select usu.cuit, usu, nombre, sum(c.saldo) as saldoTotal from Usuario usu join usu.cuentas c group by usu.cuit, usu.nombre order by sum(c.saldo) desc, usu.nombre Aplicaciones Distribuidas
Subconsultas • Si la base de datos subyacente soporta subconsultas, pueden definirse también con hibernate • from Cuenta cuentawherecuenta.saldo = ( selectmax(cuenta.saldo) from Cuenta cuenta ) • from Usuario usuwhereusu.cuitnot in ( selectu.cuitfrom Usuario u joinu.telefonos) • Si la base de datos subyacente soporta correlación, tambien pueden definirse con hibernate • from Usuario usuwherenotexists ( from Usuario u whereu.domicilio = usu.domicilio) 2011 Aplicaciones Distribuidas