Wednesday, December 30, 2015

Hibernate - Introducing HQL(Hibernate Query Language) and the Query Object

Ref:- http://www.dineshonjava.com/p/introducing-hqlhibernate-query-language.html#.VnIhn_krLIU

Hibernate created a new language named Hibernate Query Language (HQL), the syntax is quite similar to database SQL language. The main difference between is HQL uses class name instead of table name, and property names instead of column name.
Hibernate uses the following ways to retrieve objects from the database:
  • Hibernate Query Language (HQL)
  • Query By Criteria (QBC) and Query BY Example (QBE) using Criteria API
  • Native SQL queries
The most preferred way is using the Hibernate Query Language (HQL), which is an easy-to-learn and powerful query language, designed as a minimal object-oriented extension to SQL. HQL has syntax and keywords/clauses very similar to SQL. It also supports many other SQL-like features, such as aggregate functions (for example: sum(), max()) and clauses such as group byand order by clause. 

Why WE USE HQL?

Although it is possible to use native SQL queries directly with a Hibernate-based persistence layer, it is more efficient to use HQL instead. The reasons of choosing HQL over the other two methods are given below.
  • HQL allows representing SQL queries in object-oriented terms—by using objects and properties of objects.
  • Instead of returning plain data, HQL queries return the query result(s) in the form of object(s)/tuples of object(s) that are ready to be accessed, operated upon, and manipulated programmatically. This approach does away with the routine task of creating and populating objects from scratch with the "resultset" retrieved from database queried.
  • HQL fully supports polymorphic queries. That is, along with the object to be returned as a query result, all child objects (objects of subclasses) of the given object shall be returned.
  • HQL is easy to learn and implement, as its syntax and features are very similar to SQL.
  • HQL contains many advance features such as pagination, fetch join with dynamic profiling, and so forth, as compared to SQL.
  • HQL facilitates writing database-type independent queries that are converted to the native SQL dialect of the underlying database at runtime. This approach helps tap the extra features the native SQL query provides, without using a non-standard native SQL query.

HQL Syntax>>

As described earlier, most of HQL's syntax and features are very similar to SQL. An HQL query may consist of following elements:
  • Clauses
  • Aggregate functions
  • Subqueries
Clauses in the HQL are:
Aggregate functions are:
Subqueries
Subqueries are nothing but its a query within another query. Hibernate supports Subqueries if the underlying database supports it.

Table A: HQL Clauses with their description, syntax, and examples.
ClauseDescriptionSyntaxExample
fromThe simplest form of an HQL query. Specifies the object whose instances are to be returned as the query result. Commonly used with the selectclause.from object [as object_alias]* object_alias simply means another name given to refer to an object for convenience.from UserDetails as user

Will return all instances of object UserDetails.
selectSpecifies objects and properties to be returned in the query result set. Used in conjunction with the fromclause.select [object.]propertyselect user.userName from UserDetails as user

Will return all values of userName in all instances ofUserDetails.
whereSpecifies the conditions that should be satisfied by the instances returned as the query result. Used with select and/or from clause.where condition

Here, condition is a combination of logical, relational operators i.e. =, >, AND, NOT etc.
from UserDetails as user where user.userId > 2
Will return all instances of user in UserDetails whose correspondinguser.userId values are greater than 2.
order bySpecifies the order (ascending/descending) in which the properties of objects returned as query results should be listed. Used with the select and fromclauses.order by object0.property0[asc|desc][, object1.property0]...

By default, order is ascending unless specified otherwise.
from UserDetails  as user order by userId asc

Will return a list of all instances of user in ascending order of corresponding userId values.
group bySpecifies the grouping criteria using objects properties, by which the list of objects returned as a query result should be grouped together. Used with the select and/or from clause.group by object0.property0[,object1.property0]...select userId from UserDetails as user group by user.userId

Will return list of all userId instances from user grouped by corresponding values of user.

Hibernate - Select and Pagination in HQL

Ref:- http://www.dineshonjava.com/p/select-and-pagination-in-hql.html#.VnIiBfkrLIU

Pagination of search results is a common requirement for any application.
Out of performance reasons it is recommended to restrict the number of returned objects per query. In fact is a very common use case anyway that the user navigates from one page to an other. The way to define pagination is exactly the way you would define pagination in a plain HQL or Criteria query.

Using the createQuery() method of a Session object that returns a Query object.
First, instantiate the Session object using the openSession() method of SessionFactory.
Then, invoke the createQuery() method on the resulting object.
 
Query q = session.createQuery("...");
q.setFirstResult(start);
q.setMaxResults(length);
Student.java
  1. package com.sdnext.hibernate.tutorial.dto;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. import javax.persistence.Column;  
  6. import javax.persistence.Entity;  
  7. import javax.persistence.GeneratedValue;  
  8. import javax.persistence.GenerationType;  
  9. import javax.persistence.Id;  
  10. import javax.persistence.Table;  
  11.   
  12. @Entity  
  13. @Table(name="STUDENT")  
  14. public class Student implements Serializable   
  15. {  
  16.  /** 
  17.   * serialVersionUID 
  18.   */  
  19.  private static final long serialVersionUID = 8633415090390966715L;  
  20.  @Id  
  21.  @Column(name="ID")  
  22.  @GeneratedValue(strategy=GenerationType.AUTO)  
  23.  private int id;  
  24.  @Column(name="STUDENT_NAME")  
  25.  private String studentName;  
  26.  @Column(name="ROLL_NUMBER")  
  27.  private int rollNumber;  
  28.  @Column(name="COURSE")  
  29.  private String course;  
  30.  public int getId() {  
  31.   return id;  
  32.  }  
  33.  public void setId(int id) {  
  34.   this.id = id;  
  35.  }  
  36.  public String getStudentName() {  
  37.   return studentName;  
  38.  }  
  39.  public void setStudentName(String studentName) {  
  40.   this.studentName = studentName;  
  41.  }  
  42.  public int getRollNumber() {  
  43.   return rollNumber;  
  44.  }  
  45.  public void setRollNumber(int rollNumber) {  
  46.   this.rollNumber = rollNumber;  
  47.  }  
  48.  public String getCourse() {  
  49.   return course;  
  50.  }  
  51.  public void setCourse(String course) {  
  52.   this.course = course;  
  53.  }  
  54.  public String toString()  
  55.  {  
  56.   return "ROLL Number: "+rollNumber+"| Name: "+studentName+"| Course: "+course;  
  57.  }  
  58. }  
hibernate.cfg.xml
  1. <hibernate-configuration>   
  2.  <session-factory>   
  3.   <!-- Database connection settings -->  
  4.    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>   
  5.    <property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB2</property>   
  6.    <property name="connection.username">root</property>   
  7.    <property name="connection.password">root</property>   
  8.   
  9.   <!-- JDBC connection pool (use the built-in) -->  
  10.    <property name="connection.pool_size">1</property>   
  11.   
  12.   <!-- SQL dialect -->  
  13.    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>   
  14.   
  15.   <!-- Enable Hibernate's automatic session context management -->  
  16.     <property name="current_session_context_class">thread</property>   
  17.     
  18.   <!-- Disable the second-level cache -->  
  19.    <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>   
  20.   
  21.   <!-- Echo all executed SQL to stdout -->  
  22.    <property name="show_sql">true</property>   
  23.     
  24.   <!-- Drop and re-create the database schema on startup -->  
  25.    <property name="hbm2ddl.auto">update</property>   
  26.      
  27.      
  28.    <mapping class="com.sdnext.hibernate.tutorial.dto.Student">  
  29.         
  30.   </mapping></session-factory>   
  31.  </hibernate-configuration>  

HibernateTestDemo.java
  1. package com.sdnext.hibernate.tutorial;  
  2.   
  3. import java.util.List;  
  4.   
  5. import org.hibernate.Query;  
  6. import org.hibernate.Session;  
  7. import org.hibernate.SessionFactory;  
  8. import org.hibernate.cfg.AnnotationConfiguration;  
  9.   
  10. import com.sdnext.hibernate.tutorial.dto.Student;  
  11.   
  12. public class HibernateTestDemo {  
  13.  /** 
  14.   * @param args 
  15.   */  
  16.  public static void main(String[] args)   
  17.  {  
  18.   SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();  
  19.   Session session = sessionFactory.openSession();  
  20.   session.beginTransaction();  
  21.     
  22.   String SQL_QUERY = "FROM Student student";  
  23.   Query query = session.createQuery(SQL_QUERY);  
  24.   query.setFirstResult(1);//set first result start value  
  25.   query.setMaxResults(5);//number of result to be display  
  26.     
  27.   List<student> students = query.list();  
  28.   for(Student student : students)  
  29.   {  
  30.    System.out.println(student);  
  31.   }  
  32.   session.getTransaction().commit();  
  33.   session.close();  
  34.  }  
  35. }  
  36. </student>  
Output:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: select student0_.ID as ID0_, student0_.COURSE as COURSE0_, student0_.ROLL_NUMBER as ROLL3_0_, student0_.STUDENT_NAME as STUDENT4_0_ from STUDENT student0_ limit ?, ?
ROLL Number: 2| Name: Sweety Rajput| Course: PGDCP
ROLL Number: 3| Name: Adesh Rajput| Course: MA
ROLL Number: 4| Name: DEV| Course: MA
ROLL Number: 5| Name: RAJ| Course: BA
ROLL Number: 6| Name: Pradeep| Course: BA