10.1 Overview
As Hibernate is all about persisting java objects, Hibernate Query Language is a similar to SQL but in terms of Object. We may want queries with where clauses, conditions , aggregate functions etc in our application and HQL does support all these features. One of the important different between SQL and HQL is , class names are used in place of tables and object properties names are used in place of table column names. In this chapter we will discuss HQL in detail. Hibernate also supports native SQL which we will discuss later.
HQL are case insensitive.Using HQL keeps our application code database independent.
10.2 Query Object
There are several methods available in Query API ( refer Chapter 6 [ section 6.4] ) for more details on Query API.
We can create a query object, using session object. Session Object does provide a createQuery() method which takes a query as an argument and returns a Query object.
Refer below code snippet for reference
Query query = session.createQuery(“ from Object ”);
10.3 from Clause
From is the only mandatory part of HQL.. It tells hibernate from where to pull the data. For example if we have a BOOK-INFO table corresponding to Book object and we want to fire a query on Book object .
Query query = session.createQuery(“ from Book ”);
10.4 Aliases
We can assign an aliases to the objects in HQL by just adding an alias next to object OR using “as” keyword.
To assign an alias for Book object we can use any one of below syntax
Query query = session.createQuery(“ from Book as bookAlias ”);
Query query = session.createQuery(“ from Book bookAlias ”);
10.5 select Clause
To get all the columns of table we can simple use “from Object” . There is no need of select clause but if we want to get selected properties only we need to use select clause providing the list of comma separated name of the object properties .
If select statement has multiple properties to fetch then result will be an List of Object array (List<Object[] >. If select has one property then result will be list of property data type
Assuming name and author are the two properties of Book object then we can use below queries.
Query query = session.createQuery(“select name from Book ”);
Query query = session.createQuery(“ select alias.name from Book as alias ”);
To get a list of an object using select statement , we can use constructor . For example
Query query = session.createQuery(“ select new Book(name, price) from Book ”);
List<Book> books = query.list();
10.6 where Clause
We can get the filtered objects using where clause.
Assuming isbn , name and author are the properties of Book object then we can use below queries.
Query query = session.createQuery(“select name from Book where isbn=’123’ ”);
10.7 Supported Operators
a)Logical Operators - AND , OR , NOT
Query query = session.createQuery(“ select name from Book where isbn=’123’ and author=’xyz’ ”);
b) Equality Operators - =, !=
Query query = session.createQuery(“ select name from Book where isbn=’123’ and author !=’xyz’ ”);
c) Comparison Operators - < , > ,<= ,>=, LIKE, NOT LIKE , BETWEEN , NOT BETWEEN , IS NULL , IS NOT NULL , IN
Query query = session.createQuery(“ select name from Book where isbn=’123’ and author like ’%xyz’ ”);
Query query = session.createQuery(“ select name from Book where author in ( ‘xyz’ , ‘abc’ ”);
10.8 Pagination
HQL supports pagination where we can specify the starting record number and number of records to fetch. To do so we can use setFirstResult and setMaxResults methods.
Below query will fetch 15 records starting from 5th record.
Query query = session.createQuery(“select name from Book ”);
query.setFirstResult(5);
query.setMaxResults(15);
10.9 Parameters Binding
Instead of hard coding the variables values , we can bind the values at run time. We can bind the parameters using
- Name – also known as named parameter binding
- Position - also known as positional parameter binding.
10.9.1 Named Parameter Binding
- Using named parameter binding , query becomes more readable and same parameter can be reused multiple times. To use named parameter we need to use “ :name ” syntax
Query query = session.createQuery(“select name from Book where name = : bookName ”);
query.setString(“bookName”, “XYZ”);
10.9.2 Positional Parameter Binding.
– Similar to traditional JDBC Prepared Statement style , we can use ? as a place holder ( 0 based)
Query query = session.createQuery(“select name from Book where name = ? ”);
query.setString(0, “XYZ”);
10.10 Functions
We can use several functions of SQL in HQL as well. Functions like avg() , sum(), count() , max() , min() , distinct are supported.
String hql = “ select sum(book.price) from Book as book”;
Query query = session.createQuery(hql);
10.11 CRUD Operations
HQL supports INSERT, DELETE, UPDATE ,SELECT clauses. For INSERT we cannot provide arbitrary values , instead we can only use select which means select the record from database and insert it. To insert a new record , we can simply use save() method
10.12 Sorting
We can use ORDER BY clause to sort the results
Query query = session.createQuery(“select name from Book order by name desc ”);
10.13 Example
Lets create one example of Product to use HQL .
a. Product.java
package com.tutorial.hibernate; import java.util.Date; public class Product { private int productId; private String productName; private double price; private String productCategory; private Date expiryDate; private String batchNumber; public Product() { } public Product(double price, String productCategory, String batchNumber) { super(); this.price = price; this.productCategory = productCategory; this.batchNumber = batchNumber; } public int getProductId() { return productId; } public void setProductId(int productId) { this.productId = productId; } public String getProductName() { return productName; } public void setProductName(String productName) { this.productName = productName; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public String getProductCategory() { return productCategory; } public void setProductCategory(String productCategory) { this.productCategory = productCategory; } public Date getExpiryDate() { return expiryDate; } public void setExpiryDate(Date expiryDate) { this.expiryDate = expiryDate; } public String getBatchNumber() { return batchNumber; } public void setBatchNumber(String batchNumber) { this.batchNumber = batchNumber; } @Override public String toString() { return "Product [productId=" + productId + ", productName=" + productName + ", price=" + price + ", productCategory=" + productCategory + ", expiryDate=" + expiryDate + ", batchNumber=" + batchNumber + "]"; } }
b. product.hbm.xml
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.tutorial.hibernate.Product" table="PRODUCT"> <id name="productId" type="int" column="product_id"> <generator class="native"/> </id> <property name="productName" column="name" type="string"/> <property name="batchNumber" column="batch" type="string" /> <property name="productCategory" column="category" type="string" /> <property name="price" column="price" type="double" /> <property name="expiryDate" column="expiry_date" type="date" /> </class> </hibernate-mapping>
c. hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.url"> jdbc:mysql://localhost:3306/tutorial </property> <property name="hibernate.connection.username"> root </property> <property name="hibernate.connection.password"> password </property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.format_sql">true</property> <property name="show_sql">true</property> <property name="hibernate.connection.driver_class"> com.mysql.jdbc.Driver </property> <mapping resource="product.hbm.xml" /> </session-factory> </hibernate-configuration>
d. create product table
CREATE TABLE `product` ( `product_id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `batch` varchar(255) DEFAULT NULL, `category` varchar(255) DEFAULT NULL, `price` double DEFAULT NULL, `expiry_date` date DEFAULT NULL, PRIMARY KEY (`product_id`) )
e.HQLExample.java
import java.util.Date; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.tutorial.hibernate.Product; public class HQLExample { private static SessionFactory sessionFactory; public static void main(String a[]) { getSessionFactory(); //save some products in database Product product1= getProductObject("Product A", "SOAP", "AB-23-F",23.4,new Date() ); Product product2= getProductObject("Product B", "TOOTH PASTE", "XXAB-23-F",13.4,new Date() ); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); session.save(product1); session.save(product2); tx.commit(); session.close(); getAllProducts(); getProductByName("Product B"); getSpecificDetailsOfProduct(); deleteProduct(1); updateProduct(2,"Product C"); sessionFactory.close(); } private static void getSessionFactory() { Configuration cfg = new Configuration().configure(); sessionFactory = cfg.buildSessionFactory(); } private static void updateProduct(int productId, String name ) { Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); String queryString = "update Product set productName = ? where productId =? " ; Query query = session.createQuery(queryString); query.setString(0,name); query.setInteger(1,productId); query.executeUpdate(); tx.commit(); session.close(); } private static void deleteProduct(int productId) { Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); String queryString = "delete from Product where productId =? " ; Query query = session.createQuery(queryString); query.setInteger(0,productId); query.executeUpdate(); tx.commit(); session.close(); } private static void getAllProducts() { Session session = sessionFactory.openSession(); String queryString = "from Product " ; Query query = session.createQuery(queryString); List <Product> products = query.list(); for(int i=0;i<products.size();i++) { System.out.println(products.get(i)); System.out.println(); } session.close(); } private static void getProductByName(String name ) { Session session = sessionFactory.openSession(); String queryString = "from Product where productName = :name" ; Query query = session.createQuery(queryString); query.setString("name", name); Product product = (Product)query.uniqueResult(); System.out.println(product); System.out.println(); session.close(); } private static void getSpecificDetailsOfProduct() { Session session = sessionFactory.openSession(); // return list of objects (2) and each will be an array of 3 String queryString = "select productCategory, price, batchNumber from Product " ; Query query = session.createQuery(queryString); List<Object[]> product = query.list(); for(int i=0;i<product.size();i++) { Object[] data = product.get(i); System.out.println(data[0] + "," + data[1] + "," + data[2]); System.out.println(); } // Another way queryString = "select new Product( price, productCategory,batchNumber ) from Product " ; query = session.createQuery(queryString); List<Product> products = query.list(); for(int i=0;i<products.size();i++) { System.out.println(products.get(i)); } session.close(); } private static Product getProductObject(String name , String category, String batch, double price, Date expiry) { Product product = new Product(); product.setBatchNumber(batch); product.setExpiryDate(expiry); product.setPrice(price); product.setProductCategory(category); product.setProductName(name); return product; } }