What is Hibernate Criteria Query Language (HCQL)?

In the previous article, we have seen a way in which we can access the data from the database. Hibernate has provided us one more way in which we can retrieve elements i.e Hibernate Criteria Query. So, In this article, we will see what is HCQL, what is Criteria APIs and, etc.

What is HCQL?

HCQL acronyms to Hibernate Criteria Query Language. Using this language one can retrieve the data from the database as we have already done with HQL. Here, we used the Criteria Object.

  • The difference here is, it uses the Object of Criteria APIs.
  • In this, we pass the name of an entity and which lets you access any property of the object.

What are Criteria APIs?

Criteria is an API that helps us to retrieve the data from the database in the case where we need to fetch the data from the database based on some filtration or condition. There are several methods present in org.hibernate.Criteria interface to perform operations on an object. Following is the syntax we will see:

Criteria c = session.createCriteria(EntityName.class);
  • Here, the session interface calls the createCriteria() method with the Entityname being passed to it.
  • Then, the hibernate we’ll create a Criteria object.
  • At last, it will return the instance of Entity class that you will pass.

While creating web applications, sometimes we need to add search functionality for this we can use this Criteria Query.

What are the Methods of Hibernate Criteria?

  • public Criteria add(Criteria c): This method is used to add a restriction(Restriction we will see below)
  • public Criteria setMaxResult(int resultTotal): This method retrieves the result based on the parameters we will pass. 
  • public Criteria setFirstResult(int firstResult): This method is used to set the position of the first result.
  • public Criteria addOrder(Order o): This method is used to specify Order.
  • public List list(): This method contains the list of Objects.
  • public Criteria setProjection(Projection p): This method is used to specify the projections.

Let us see some of the classes available in HCQL

What is Restriction Class?

When we want to apply some filtration or condition we use the Restriction class on the Criterion object. We have some Factory methods of Restriction that we will see in detail:

  • public static SimpleExpression lt(String property_name, Object value): This method sets the less than restriction to the property.
  • public static SimpleExpression gt(String property_name, Object value): This method sets the greater than restriction to the property.
  • public static SimpleExpression ge(String property_name, Object value): This method sets the greater than or equal to restriction to the property.
  • public static SimpleExpression le(String property_name, Object value): This method sets the less than or equal to restriction to the property.
  • public static SimpleExpression eq(String property_name, Object value): This method sets the equal restriction to the property.
  • public static SimpleExpression ne(String property_name, Object value): This method sets the not equal restriction to the property.
  • public static SimpleExpression like(String property_name, Object value): This method sets the like restriction to the property.
  • public static Criterion between (String property_name, Object low, Object high): This method sets the between restriction to the property.

Examples of lt(),  gt(), ge(), le(), ne(), between():

Consider there is a class Student and we want to fetch the marks of students based on the condition we can use this method in the following way

//Students marks less than 30
Criteria c = session.createCriteria(Student.class);
c.add(Restrictions.lt("marks",30));
List<Student> results = c.list();

//Students marks greater than 30
Criteria c = session.createCriteria(Student.class);
c.add(Restrictions.gt("marks",30));
List<Student> results = c.list();

//Students marks less than or equal to 30
Criteria c = session.createCriteria(Student.class);
c.add(Restrictions.le("marks",30));
List<Student> results = c.list();

//Students marks greater than or equal to 30
Criteria c = session.createCriteria(Student.class);
c.add(Restrictions.ge("marks",30));
List<Student> results = c.list();

//Students marks not equal to 30
Criteria c = session.createCriteria(Student.class);
c.add(Restrictions.ne("marks",30));
List<Student> results = c.list();

//Students marks equal to 30
Criteria c = session.createCriteria(Student.class);
c.add(Restrictions.eq("marks",30));
List<Student> results = c.list();


//Students marks between to 30 & 40 
Criteria c = session.createCriteria(Student.class);
c.add(Restrictions.eq("marks",30,40)); 
List<Student> results = c.list();

//Students name starts with A%
Criteria c = session.createCriteria(Student.class);
c.add(Restrictions.like("name","A%"));
List<Student> results = c.list();

we can also combine the criteria result(i.e we can have AND | OR operation ). considering we have two restrictions to criteria query, like this:

Criteria c = session.createCriteria(Student.class);
Criterion marks = Restrictions.lt("marks",30);
Criterion name =  Restrictions.like("name","A%");
// OR OPERATION
LogicalExpression orExp = Restrictions.or(marks, name);
c.add( orExp );
//  AND OPERATION
LogicalExpression andExp = Restrictions.and(marks, name);
c.add( andExp );
List results = c.list();

What is Order Class?

When we want to fetch the data from the database in a particular order like it can be ascending or descending we use the Order class in Hibernate. We have the following two methods here.

  • public static Order asc(String property_name): This method is used to fetch the results in ascending order.
  • public static Order desc(String property_name): This method is used to fetch the results in descending order.

Example:

In this, we will fetch the list of students roll_no in ascending orders.

Crietria c=session.createCriteria(Student.class);  
c.addOrder(Order.asc("roll_no"));  
List<Student> list=c.list();

How to perform Pagination using HCQL?

Pagination is a concept in which we divide the data into pages and displayed the data on multiple pages within one web page. This can easily be done in HCQL using the above methods that we have discussed.

Consider a Student record in the database and we want to show five records per page so we can set method setMaxResult(5). 

Criteria c= session.createCriteria(Student.class);
c.setFirstResult(1);
c.setMaxResults(5);
List<Student> result= (List<Student>) c.list();

How to add Projection & Aggregation in Hibernate using Criteria?

The data when we get from the database in the form of rows and columns is called a projection of the data. Criteria APIs provide us the Projection class (in org.hibernate.criterion.Projection) and it provides some factory methods to perform the aggregate operation. we have the following aggregate methods present in this class:

  • avg(String property_name): This method gets the average of the property’s value.
  • sum(String property_name): This method gets the sum of the property’s value.
  • count(String property_name): This method gets the count of the property’s value.
  • countDistinct(String property_name): This method gets the unique count of the property’s value.
  • max(String property_name): This method gets the maximum value of the property’s values.
  • min(String property_name): This method gets the minimum value of the property’s values.

Example:

Criteria c= session.createCriteria(Student.class);

// It shows the total row count.
c.setProjection(Projections.rowCount());

// To shows the maximum of a property.
c.setProjection(Projections.max("marks"));

// To shows the minimum of a property.
c.setProjection(Projections.min("marks"));

// To shows the average of a property.
c.setProjection(Projections.avg("maks"));

// To shows the distinct count of a property.
c.setProjection(Projections.countDistinct("name"));

// To get sum of a property.
c.setProjection(Projections.sum("marks"));

Example to show the use of HCQL in Web application

In this, we will create a search functionality using Criteria Query Objects using the following steps:

First, we will need a Helper class to include the Factory of sessions i.e DataSource.java.

package com.abc;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibDataSource {

  private static SessionFactory factory;

  private HibDataSource() {

  }

  public static SessionFactory getSessionfactory() {
    if (factory == null) {
      factory = new Configuration().configure().buildSessionFactory();
    }

    return factory;

  }

  public static Session getSession() {
    Session session = getSessionfactory().openSession();
    return session;
  }

  public static void closeSession(Session session) {
    if (session != null) {
      session.close();
    }
  }

}

Then, we will create a configuration file i.e hibernate.cfg.xml 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/classproject</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">root</property>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.hbm2ddl.auto">update</property>
    <property name="hibernate.c3p0.min_size">10</property>
    <property name="hibernate.c3p0.max_size">100</property>
    <property name="hibernate.c3p0.acquire_increment">10</property>
    <property name="hibernate.c3p0.timeout">10</property>
    <property name="hibernate.c3p0.">10</property>
    <mapping class="com.abc.Student" />
  </session-factory>
</hibernate-configuration>

Now, we will create the Student class to set and get the data. Here, we are creating an annotation-based class so we won’t need a mapping file now. (How to create an annotated class you can check here How to use Annotation in Hibernate?)

package com.abc;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity // specifies that class in an entity
@Table(name = "student") // defines the table
public class Student {

  @Id // indicate it is a primary key of the table.
  @GeneratedValue(strategy = GenerationType.IDENTITY) // annotation is to
                            // configure the way of
                            // increment of the
                            // specified
                            // column(field).
  @Column(name = "id")
  private int id;

  @Column(name = "name")
  private String nameOfStudent;

  @Column(name = "address")
  private String add;

  @Column(name = "collegename")
  private String cn;

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getNameOfStudent() {
    return nameOfStudent;
  }

  public void setNameOfStudent(String nameOfStudent) {
    this.nameOfStudent = nameOfStudent;
  }

  public String getAdd() {
    return add;
  }

  public void setAdd(String add) {
    this.add = add;
  }

  public String getCn() {
    return cn;
  }

  public void setCn(String cn) {
    this.cn = cn;
  }

  public Student() {
    super();
  }

}

Now, we will create a Model class to include the business logic means to get the search result using Criteria query.

package com.abc;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;

public class StudentModel {

  public List search(Student s) {
    List list = null;
    Session session = null;
    Transaction tx = null;
    session = HibDataSource.getSession();
    String a = s.getNameOfStudent();
    System.out.println("a is " + a);
    Criteria c = session.createCriteria(Student.class);
    if (s.getId() > 0) {
      System.out.println("bean id here " + s.getId());
      c.add(Restrictions.eq("id", s.getId()));
    }
    if (s.getNameOfStudent() != null && s.getNameOfStudent().length() > 0) {
      System.out.println("in name");
      c.add(Restrictions.like("nameOfStudent", s.getNameOfStudent() + "%"));
    }
    list = c.list();
    return list;
  }

}

Now, we will create a controller for Search i.e SearchHibernate.java where we will handle all the requests & response.

package com.abc;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class SearchHibernate
 */
@WebServlet("/SearchHibernate")
public class SearchHibernate extends HttpServlet {
  private static final long serialVersionUID = 1L;

  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // TODO Auto-generated method stub
    System.out.println("inisde");

    String studentname = request.getParameter("name");
    Student s = new Student();
    s.setNameOfStudent(studentname);
    StudentModel model = new StudentModel();
    List l = model.search(s);
    System.out.println("list is " + l);
    if (l == null && l.size() == 0) {
      request.setAttribute("No record", "no");
    }
    request.setAttribute("l", l);
    request.getRequestDispatcher("index.jsp").forward(request, response);

  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // TODO Auto-generated method stub
    String studentname = request.getParameter("name");
    Student s = new Student();
    s.setNameOfStudent(studentname);
    StudentModel model = new StudentModel();
    List l = model.search(s);
    System.out.println("list is " + l);
    if (l == null && l.size() == 0) {
      request.setAttribute("No record", l);
    }
    request.setAttribute("l", l);
    request.getRequestDispatcher("index.jsp").forward(request, response);
  }

}

Now we will create an index.jsp and home.jsp file to view the data.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<a href="SearchHibernate">Index page</a>
</body>
</html>
<%@page import="com.abc.Servletutility"%>
<%@page import="com.abc.Student"%>
<%@page import="com.abc.HibDataSource"%>
<%@page import="org.hibernate.*"%>
<%@page import="org.hibernate.cfg.*"%>
<%@page import="java.util.*" %>
<html>
<head>
<title>Search by Hibernate Query Language</title>
</head>
<body>
<form action="SearchHibernate" method="post">
<table align="center"><tr><td>
<%request.getAttribute("no"); %>
Enter Name <input type="text" name="name" >
<button type="submit">Search</button>
<button type="reset">Reset</button>
</td></tr>
</table>
<h3 align="center">List of Students</h3>
<table border="2" align="center">

<tr>
<th>Id</th>
<th>Name</th>
<th>Address</th>
<th>College Name</th></tr>
<%
Session s=null;
Transaction tx=null;
s=HibDataSource.getSession();
List l=(List)request.getAttribute("l");
Iterator it=l.iterator();
while(it.hasNext()){
Student student=(Student)it.next();
%>


<tr><td><%=student.getId() %></td>
<td><%=student.getNameOfStudent() %></td>
<td><%=student.getAdd() %></td>
<td><%=student.getCn() %></td>
</tr>



<%} %>
</table>
</form>
</body>
</html>

Output:

Advantages of HCQL

  • We have already seen, using HCQL we can perform pagination in the easiest way.
  • HCQL is database-independent means it will be executed on every relational database.
  • It supports Dynamic queries.
  • It supports Projection so that we can perform all the aggregate functions.

Thus this was all about Hibernate Criteria Query Language which has provided us with Criteria APIs and we can use it in our application.

In the next article of this tutorial, we will cover How to use native SQL in Hibernate?