Pages

Monday, October 25, 2010

Hibernate Query Language

Hibernate Query Language or HQL for short is extremely powerful query language. HQL is much like SQL  and are case-insensitive, except for the names of the Java Classes and properties. Hibernate Query Language is used to execute queries against database. Hibernate automatically generates the sql query and execute it against underlying database if HQL is used in the application. HQL is based on the relational object models and makes the SQL object oriented. Hibernate Query Language uses Classes and properties instead of tables and columns. Hibernate Query Language is extremely powerful and it supports Polymorphism, Associations, Much less verbose than SQL.

There are other options that can be used while using Hibernate. These are Query By Criteria (QBC) and Query BY Example (QBE) using Criteria API and the Native SQL queries

Why to use HQL?

Full support for relational operations: HQL allows representing SQL queries in the form of objects. Hibernate Query Language uses Classes and properties instead of tables and columns.
   
Return result as Object: The HQL queries return the query result(s) in the form of object(s), which is easy to use. This eliminates the need of creating the object and populate the data from result set.
   
Polymorphic Queries: HQL fully supports polymorphic queries. Polymorphic queries results the query results along with all the child objects if any.
   
Easy to Learn: Hibernate Queries are easy to learn and it can be easily implemented in the applications.
   
Support for Advance features: HQL contains many advance features such as pagination, fetch join with dynamic profiling, Inner/outer/full joins, Cartesian products. It also supports Projection, Aggregation (max, avg) and grouping, Ordering, Sub queries and SQL function calls.
  
Database independent: Queries written in HQL are database independent (If database supports the underlying feature).

Understanding HQL Syntax
Any Hibernate Query Language may consist of following elements:
  • Clauses
  • Aggregate functions
  • Subqueries

Clauses in the HQL are:
  • from
  • select
  • where
  • order by
  • group by

Aggregate functions are:
  • avg(…),sum(…),min(…),max(…)
  • count(*)
  • count(...), count(distinct ...), count(all...)

Subqueries  
  • Subqueries are nothing but its a query within another query. Hibernate supports Subqueries if the underlying database supports it.

Clauses
FROM
SELECT * FROM EMPLOYEE  -------- SQL
FROM EMPLOYEE ---------- HQL
Specified Columns:
SELECT ID,EMPNAME FROM EMPLOYEE -----------SQL
SELECT EMP.ID, EMP.EMPNAME FROM EMPLOYEE EMP -----------HQL


WHERE
SELECT * FROM EMPLOYEE WHERE ID=? -----------SQL
FROM EMPLOYEE WHERE ID=:ID --------------HQL


ORDER BY
SELECT * FROM EMPLOYEE WHERE EMPNAME=? ORDER BY ID ASC ------------SQL
FROM EMPLOYEE EMP WHERE EMP.EMPNAME=:NAME ORDER BY EMP.ID ASC-----HQL


Retrieve all the records from employee table


String queryStr= "FROM EMPLOYEE";
Query query = session.createQuery(queryStr);
List empList = query.list();


empList contains N number of employee objects, Each employee object contains one record.

Query:
An object-oriented representation of a Hibernate query. A Query instance is obtained by calling Session.createQuery(). This interface exposes some extra functionality beyond that provided by Session.iterate() and Session.find():

  • a particular page of the result set may be selected by calling setMaxResults(), setFirstResult()
  • named query parameters may be used
  • the results may be returned as an instance of ScrollableResults

Queries are executed by calling list(), scroll() or iterate(). A query may be re-executed by subsequent invocations. Its lifespan is, however, bounded by the lifespan of the Session that created it.

Implementors are not intended to be threadsafe

Iterator()
Return the query results as an Iterator. If the query contains multiple results pre row, the results are returned in an instance of Object[].

Entities returned as results are initialized on demand. The first SQL query returns identifiers only.

list()
Return the query results as a List. If the query contains multiple results pre row, the results are returned in an instance of Object[].

Scroll()
Return the query results as ScrollableResults. The scrollability of the returned results depends upon JDBC driver support for scrollable ResultSets.

***Note : If we are selecting all the columns data then type cast to Employee and if we are selecting some of the columns or applying aggregate functions then type cast to object array or the required data type
 ---------------------------------------------------------------------------------------------------
 String queryStr = "FROM EMPLOYEE";
Query query = session.createQuery(queryStr);

for (Iterator it = query.iterate(); it.hasNext();) {
           Employee emp = (Employee) it.next();  ---------- its valid
           Object obj = (Object[]) it.next();-------------------its invalid
}
Here we are selecting all the columns data so type cast to Employee.


----------------------------------------------------------------------------------------
String queryStr = "SELECT EMP.ID, EMP.EMPNAME FROM EMPLOYEE EMP";
Query query = session.createQuery(queryStr);
for (Iterator it = query.iterate(); it.hasNext();) {
           Employee emp = (Employee) it.next();  ---------- its invalid
           Object obj = (Object[]) it.next();-------------------its valid
}

Here we are giving the column names so type cast to Object[].


---------------------------------------------------------------------------------------
String queryStr = "SELECT EMP.ID FROM EMPLOYEE EMP";
Query query = session.createQuery(queryStr);
for (Iterator it = query.iterate(); it.hasNext();) {
           Employee emp = (Employee) it.next();  ---------- its invalid
           Object obj = (Object[]) it.next();-------------------its invalid
           Object obj = (Object) it.next();-------------------its valid
           Long obj = (Long) it.next();-------------------its valid 
}
Here we are giving one column name so type cast to object or the required data type.
-------------------------------------------------------------------------------------------

String queryStr = "SELECT MAX(EMP.ID), MIN(EMP.EMPNAME) FROM EMPLOYEE EMP";
Query query = session.createQuery(queryStr);
for (Iterator it = query.iterate(); it.hasNext();) {
           Employee emp = (Employee) it.next();  ---------- its invalid
           Object obj = (Object[]) it.next();-------------------its valid
           Object obj = (Object) it.next();-------------------its invalid
           for(int i =0;i
             System.out.println(obj[i]);
         }

}
Here we are giving two Aggregate functions and dont type cast to Object or Employee object.

Working with Positional Parameters

String sqlStr = "FROM EMPLOYEE EMP WHERE EMP.ID AND EMP.EMPNAME LIKE ?";
Query qry = session.createQuery(sqlStr);
qry.setLong(0, new Long(1));
qry.setString (1,"Vardhan%");

Here we are giving ? while we set the values to the query the position should start with 0. In the JDBC, prepared statement position starts with 1. 

Working with Named Parameters
Named parameter will be any name which will be given in the query instead of ?
Syntax:
   :name
Any name which starts with : is named parameter.

String sqlStr = "FROM EMPLOYEE EMP WHERE EMP.ID>:ID AND EMP.EMPNAME LIKE :NAME";
Query qry = session.createQuery(sqlStr);
qry.setLong("ID", new Long(1));
qry.setString ("NAME","Vardhan%");

***Note:- We can use the positional parameters and the named parameters combination in a single query. order should be first positional and next named parameters vice versa not possible

sqlStr = "FROM EMPLOYEE EMP WHERE EMP.ID>? AND EMP.EMPNAME LIKE :NAME"; --- valid


sqlStr = "FROM EMPLOYEE EMP WHERE EMP.ID>:ID AND EMP.EMPNAME LIKE ?; --- invalid