HQL - Hibernate 查询语言 - 示例教程

HQL或Hibernate Query Language是Hibernate框架的面向对象查询语言。HQL与SQL非常相似,不同之处在于我们使用对象而不是表名,这使它更接近面向对象编程。

Hibernate查询语言- HQL

hibernate query language,hql example,hql query,hibernate query,hibernate join,hql join,hql tutorialHQL和大小写敏感性 :HQL不区分大小写,Java类和变量名除外。所以SeLeCTsELEctSELECT一样,但是com.journaldev.model.Employeecom.journaldev.model.EMPLOYEE不一样。HQL中一些通常支持的条款是:

1.HQL from :HQL from与SQL中的SELECT子句相同,From EmployeeSelect* from Employee相同。我们也可以创建别名,如From Employee EmpFrom Employee as Emp。 2.HQL Join :HQL支持内部Join、Left Out Join、Right Out Join和Full Join。例如,Select e.name,a.City from Employee e Enter Join e.Address a。在这个查询中,Employee类应该有一个名为Address的变量。我们将在示例代码中对其进行研究。 3.聚合函数 :HQL支持COUNT(* )、COUNT(DISTINCT X)、MIN()、max()、avg()、sum()等常用聚合函数。 4.表达式 :HQL支持算术表达式(+、-、* 、/)、二元比较运算符(=、>=、<=、<>、!=、LIKE)、逻辑运算(AND、OR、NOT)等。 5.HQL还支持ORDRE BY和GROUP BY子句。 6.HQL也支持像SQL查询一样的子查询。 7.HQL也支持DDL、DML和执行存储过程。

让我们看一个在我们的程序中使用HQL的简单示例。

HQL数据库设置示例

我正在使用MySQL数据库作为我的示例,下面的脚本将创建两个表Employee和Address。它们有一对一的映射,我正在为我的示例插入一些演示数据。

 1CREATE TABLE `Employee` (
 2  `emp_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 3  `emp_name` varchar(20) NOT NULL,
 4  `emp_salary` double(10,0) NOT NULL DEFAULT '0',
 5  PRIMARY KEY (`emp_id`)
 6) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
 7
 8CREATE TABLE `Address` (
 9  `emp_id` int(11) unsigned NOT NULL,
10  `address_line1` varchar(50) NOT NULL DEFAULT '',
11  `zipcode` varchar(10) DEFAULT NULL,
12  `city` varchar(20) DEFAULT NULL,
13  PRIMARY KEY (`emp_id`),
14  CONSTRAINT `emp_fk_1` FOREIGN KEY (`emp_id`) REFERENCES `Employee` (`emp_id`)
15) ENGINE=InnoDB DEFAULT CHARSET=utf8;
16
17INSERT INTO `Employee` (`emp_id`, `emp_name`, `emp_salary`)
18VALUES
19    (1, 'Pankaj', 100),
20    (2, 'David', 200),
21    (3, 'Lisa', 300),
22    (4, 'Jack', 400);
23
24INSERT INTO `Address` (`emp_id`, `address_line1`, `zipcode`, `city`)
25VALUES
26    (1, 'Albany Dr', '95129', 'San Jose'),
27    (2, 'Arques Ave', '95051', 'Santa Clara'),
28    (3, 'BTM 1st Stage', '560100', 'Bangalore'),
29    (4, 'City Centre', '100100', 'New Delhi');
30    
31commit;

在您正在使用的Eclipse或IDE中创建一个Maven项目,我们的最终项目将如下图所示。hql示例,hql教程,hql查询,hql Join example

Hibernate Maven配置

我们最终的pom.xml包含Hibernate和MySQL驱动程序的依赖项。

 1<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 2  <modelVersion>4.0.0</modelVersion>
 3  <groupId>com.journaldev.hibernate</groupId>
 4  <artifactId>HQLExample</artifactId>
 5  <version>0.0.1-SNAPSHOT</version>
 6  <dependencies>
 7    <dependency>
 8    	<groupId>org.hibernate</groupId>
 9    	<artifactId>hibernate-core</artifactId>
10    	<version>4.3.5.Final</version>
11    </dependency>
12    <dependency>
13    	<groupId>mysql</groupId>
14    	<artifactId>mysql-connector-java</artifactId>
15    	<version>5.0.5</version>
16    </dependency>
17  </dependencies>
18</project>

Hibernate配置XML

我们的Hibernate配置XML文件包含与数据库连接相关的属性和映射类。我将使用注解进行Hibernate映射。Hibernate.cfg.xml代码:

 1<?xml version="1.0" encoding="UTF-8"?>
 2<!DOCTYPE hibernate-configuration PUBLIC
 3    	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4    	"https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 5<hibernate-configuration>
 6    <session-factory>
 7        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
 8        <property name="hibernate.connection.password">pankaj123</property>
 9        <property name="hibernate.connection.url">jdbc:mysql://localhost/TestDB</property>
10        <property name="hibernate.connection.username">pankaj</property>
11        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
12
13        <property name="hibernate.current_session_context_class">thread</property>
14        <property name="hibernate.show_sql">true</property>
15
16        <mapping class="com.journaldev.hibernate.model.Employee"/>
17        <mapping class="com.journaldev.hibernate.model.Address"/>
18    </session-factory>
19</hibernate-configuration>

Hibernate SessionFactory实用程序类

我们有一个实用程序类来配置Hibernate SessionFactory。

 1package com.journaldev.hibernate.util;
 2
 3import org.hibernate.SessionFactory;
 4import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
 5import org.hibernate.cfg.Configuration;
 6import org.hibernate.service.ServiceRegistry;
 7
 8public class HibernateUtil {
 9
10    private static SessionFactory sessionFactory;
11    
12    private static SessionFactory buildSessionFactory() {
13        try {
14            // Create the SessionFactory from hibernate.cfg.xml
15        	Configuration configuration = new Configuration();
16        	configuration.configure("hibernate.cfg.xml");
17        	System.out.println("Hibernate Configuration loaded");
18        	
19        	ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
20        	System.out.println("Hibernate serviceRegistry created");
21        	
22        	SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
23        	
24            return sessionFactory;
25        }
26        catch (Throwable ex) {
27            System.err.println("Initial SessionFactory creation failed." + ex);
28            ex.printStackTrace();
29            throw new ExceptionInInitializerError(ex);
30        }
31    }
32    
33    public static SessionFactory getSessionFactory() {
34    	if(sessionFactory == null) sessionFactory = buildSessionFactory();
35        return sessionFactory;
36    }
37}

基于注释映射的模型类

我们带有JPA注释的模型类如下所示。

 1package com.journaldev.hibernate.model;
 2
 3import javax.persistence.Column;
 4import javax.persistence.Entity;
 5import javax.persistence.GeneratedValue;
 6import javax.persistence.GenerationType;
 7import javax.persistence.Id;
 8import javax.persistence.OneToOne;
 9import javax.persistence.Table;
10
11import org.hibernate.annotations.Cascade;
12
13@Entity
14@Table(name = "EMPLOYEE")
15public class Employee {
16
17    @Id
18    @GeneratedValue(strategy = GenerationType.IDENTITY)
19    @Column(name = "emp_id")
20    private long id;
21
22    @Column(name = "emp_name")
23    private String name;
24
25    @Column(name = "emp_salary")
26    private double salary;
27
28    @OneToOne(mappedBy = "employee")
29    @Cascade(value = org.hibernate.annotations.CascadeType.ALL)
30    private Address address;
31
32    public long getId() {
33    	return id;
34    }
35
36    public void setId(long id) {
37    	this.id = id;
38    }
39
40    public Address getAddress() {
41    	return address;
42    }
43
44    public void setAddress(Address address) {
45    	this.address = address;
46    }
47
48    public String getName() {
49    	return name;
50    }
51
52    public void setName(String name) {
53    	this.name = name;
54    }
55
56    public double getSalary() {
57    	return salary;
58    }
59
60    public void setSalary(double salary) {
61    	this.salary = salary;
62    }
63
64}
 1package com.journaldev.hibernate.model;
 2
 3import javax.persistence.Column;
 4import javax.persistence.Entity;
 5import javax.persistence.GeneratedValue;
 6import javax.persistence.Id;
 7import javax.persistence.OneToOne;
 8import javax.persistence.PrimaryKeyJoinColumn;
 9import javax.persistence.Table;
10
11import org.hibernate.annotations.GenericGenerator;
12import org.hibernate.annotations.Parameter;
13
14@Entity
15@Table(name = "ADDRESS")
16public class Address {
17
18    @Id
19    @Column(name = "emp_id", unique = true, nullable = false)
20    @GeneratedValue(generator = "gen")
21    @GenericGenerator(name = "gen", strategy = "foreign", 
22    			parameters = { @Parameter(name = "property", value = "employee") })
23    private long id;
24
25    @Column(name = "address_line1")
26    private String addressLine1;
27
28    @Column(name = "zipcode")
29    private String zipcode;
30
31    @Column(name = "city")
32    private String city;
33
34    @OneToOne
35    @PrimaryKeyJoinColumn
36    private Employee employee;
37
38    public long getId() {
39    	return id;
40    }
41
42    public void setId(long id) {
43    	this.id = id;
44    }
45
46    public String getAddressLine1() {
47    	return addressLine1;
48    }
49
50    public void setAddressLine1(String addressLine1) {
51    	this.addressLine1 = addressLine1;
52    }
53
54    public String getZipcode() {
55    	return zipcode;
56    }
57
58    public void setZipcode(String zipcode) {
59    	this.zipcode = zipcode;
60    }
61
62    public String getCity() {
63    	return city;
64    }
65
66    public void setCity(String city) {
67    	this.city = city;
68    }
69
70    public Employee getEmployee() {
71    	return employee;
72    }
73
74    public void setEmployee(Employee employee) {
75    	this.employee = employee;
76    }
77
78}

HQL示例测试类

让我们看看如何在Java程序中使用HQL。

 1package com.journaldev.hibernate.main;
 2
 3import java.util.Arrays;
 4import java.util.List;
 5
 6import org.hibernate.Query;
 7import org.hibernate.Session;
 8import org.hibernate.SessionFactory;
 9import org.hibernate.Transaction;
10
11import com.journaldev.hibernate.model.Employee;
12import com.journaldev.hibernate.util.HibernateUtil;
13
14public class HQLExamples {
15
16    @SuppressWarnings("unchecked")
17    public static void main(String[] args) {
18    	
19    	//Prep work
20    	SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
21    	Session session = sessionFactory.getCurrentSession();
22    	
23    	//HQL example - Get All Employees
24    	Transaction tx = session.beginTransaction();
25    	Query query = session.createQuery("from Employee");
26    	List<Employee> empList = query.list();
27    	for(Employee emp : empList){
28    		System.out.println("List of Employees::"+emp.getId()+","+emp.getAddress().getCity());
29    	}
30    	
31    	//HQL example - Get Employee with id
32    	query = session.createQuery("from Employee where id= :id");
33    	query.setLong("id", 3);
34    	Employee emp = (Employee) query.uniqueResult();
35    	System.out.println("Employee Name="+emp.getName()+", City="+emp.getAddress().getCity());
36    	
37    	//HQL pagination example
38    	query = session.createQuery("from Employee");
39    	query.setFirstResult(0); //starts with 0
40    	query.setFetchSize(2);
41    	empList = query.list();
42    	for(Employee emp4 : empList){
43    		System.out.println("Paginated Employees::"+emp4.getId()+","+emp4.getAddress().getCity());
44    	}
45    	
46    	//HQL Update Employee
47    	query = session.createQuery("update Employee set name= :name where id= :id");
48    	query.setParameter("name", "Pankaj Kumar");
49    	query.setLong("id", 1);
50    	int result = query.executeUpdate();
51    	System.out.println("Employee Update Status="+result);
52
53    	//HQL Delete Employee, we need to take care of foreign key constraints too
54    	query = session.createQuery("delete from Address where id= :id");
55    	query.setLong("id", 4);
56    	result = query.executeUpdate();
57    	System.out.println("Address Delete Status="+result);
58    	
59    	query = session.createQuery("delete from Employee where id= :id");
60    	query.setLong("id", 4);
61    	result = query.executeUpdate();
62    	System.out.println("Employee Delete Status="+result);
63    	
64    	//HQL Aggregate function examples
65    	query = session.createQuery("select sum(salary) from Employee");
66    	double sumSalary = (Double) query.uniqueResult();
67    	System.out.println("Sum of all Salaries= "+sumSalary);
68    	
69    	//HQL join examples
70    	query = session.createQuery("select e.name, a.city from Employee e "
71    			+ "INNER JOIN e.address a");
72    	List<Object[]> list = query.list();
73    	for(Object[] arr : list){
74    		System.out.println(Arrays.toString(arr));
75    	}
76    	
77    	//HQL group by and like example
78    	query = session.createQuery("select e.name, sum(e.salary), count(e)"
79    			+ " from Employee e where e.name like '%i%' group by e.name");
80    	List<Object[]> groupList = query.list();
81    	for(Object[] arr : groupList){
82    		System.out.println(Arrays.toString(arr));
83    	}
84    	
85    	//HQL order by example
86    	query = session.createQuery("from Employee e order by e.id desc");
87    	empList = query.list();
88    	for(Employee emp3 : empList){
89    		System.out.println("ID Desc Order Employee::"+emp3.getId()+","+emp3.getAddress().getCity());
90    	}
91    	
92    	//rolling back to save the test data
93    	tx.rollback();
94    	
95    	//closing hibernate resources
96    	sessionFactory.close();
97    }
98
99}

请注意,我正在使用HQL进行选择、更新和删除操作。它还展示了如何使用HQL Join和HQL聚合函数。当我运行上面的hql示例程序时,我们得到以下输出。

 1May 22, 2014 1:55:37 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
 2INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
 3May 22, 2014 1:55:37 PM org.hibernate.Version logVersion
 4INFO: HHH000412: Hibernate Core {4.3.5.Final}
 5May 22, 2014 1:55:37 PM org.hibernate.cfg.Environment <clinit>
 6INFO: HHH000206: hibernate.properties not found
 7May 22, 2014 1:55:37 PM org.hibernate.cfg.Environment buildBytecodeProvider
 8INFO: HHH000021: Bytecode provider name : javassist
 9May 22, 2014 1:55:37 PM org.hibernate.cfg.Configuration configure
10INFO: HHH000043: Configuring from resource: hibernate.cfg.xml
11May 22, 2014 1:55:37 PM org.hibernate.cfg.Configuration getConfigurationInputStream
12INFO: HHH000040: Configuration resource: hibernate.cfg.xml
13May 22, 2014 1:55:37 PM org.hibernate.cfg.Configuration doConfigure
14INFO: HHH000041: Configured SessionFactory: null
15Hibernate Configuration loaded
16Hibernate serviceRegistry created
17May 22, 2014 1:55:37 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
18WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)
19May 22, 2014 1:55:37 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
20INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost/TestDB]
21May 22, 2014 1:55:37 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
22INFO: HHH000046: Connection properties: {user=pankaj, password=****}
23May 22, 2014 1:55:37 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
24INFO: HHH000006: Autocommit mode: false
25May 22, 2014 1:55:37 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
26INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
27May 22, 2014 1:55:37 PM org.hibernate.dialect.Dialect <init>
28INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
29May 22, 2014 1:55:37 PM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
30INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
31May 22, 2014 1:55:38 PM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
32INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
33May 22, 2014 1:55:38 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
34INFO: HHH000397: Using ASTQueryTranslatorFactory
35Hibernate: select employee0_.emp_id as emp_id1_1_, employee0_.emp_name as emp_name2_1_, employee0_.emp_salary as emp_sala3_1_ from EMPLOYEE employee0_
36Hibernate: select address0_.emp_id as emp_id1_0_0_, address0_.address_line1 as address_2_0_0_, address0_.city as city3_0_0_, address0_.zipcode as zipcode4_0_0_, employee1_.emp_id as emp_id1_1_1_, employee1_.emp_name as emp_name2_1_1_, employee1_.emp_salary as emp_sala3_1_1_ from ADDRESS address0_ left outer join EMPLOYEE employee1_ on address0_.emp_id=employee1_.emp_id where address0_.emp_id=?
37Hibernate: select address0_.emp_id as emp_id1_0_0_, address0_.address_line1 as address_2_0_0_, address0_.city as city3_0_0_, address0_.zipcode as zipcode4_0_0_, employee1_.emp_id as emp_id1_1_1_, employee1_.emp_name as emp_name2_1_1_, employee1_.emp_salary as emp_sala3_1_1_ from ADDRESS address0_ left outer join EMPLOYEE employee1_ on address0_.emp_id=employee1_.emp_id where address0_.emp_id=?
38Hibernate: select address0_.emp_id as emp_id1_0_0_, address0_.address_line1 as address_2_0_0_, address0_.city as city3_0_0_, address0_.zipcode as zipcode4_0_0_, employee1_.emp_id as emp_id1_1_1_, employee1_.emp_name as emp_name2_1_1_, employee1_.emp_salary as emp_sala3_1_1_ from ADDRESS address0_ left outer join EMPLOYEE employee1_ on address0_.emp_id=employee1_.emp_id where address0_.emp_id=?
39Hibernate: select address0_.emp_id as emp_id1_0_0_, address0_.address_line1 as address_2_0_0_, address0_.city as city3_0_0_, address0_.zipcode as zipcode4_0_0_, employee1_.emp_id as emp_id1_1_1_, employee1_.emp_name as emp_name2_1_1_, employee1_.emp_salary as emp_sala3_1_1_ from ADDRESS address0_ left outer join EMPLOYEE employee1_ on address0_.emp_id=employee1_.emp_id where address0_.emp_id=?
40List of Employees::1,San Jose
41List of Employees::2,Santa Clara
42List of Employees::3,Bangalore
43List of Employees::4,New Delhi
44Hibernate: select employee0_.emp_id as emp_id1_1_, employee0_.emp_name as emp_name2_1_, employee0_.emp_salary as emp_sala3_1_ from EMPLOYEE employee0_ where employee0_.emp_id=?
45Employee Name=Lisa, City=Bangalore
46Hibernate: select employee0_.emp_id as emp_id1_1_, employee0_.emp_name as emp_name2_1_, employee0_.emp_salary as emp_sala3_1_ from EMPLOYEE employee0_
47Paginated Employees::1,San Jose
48Paginated Employees::2,Santa Clara
49Paginated Employees::3,Bangalore
50Paginated Employees::4,New Delhi
51Hibernate: update EMPLOYEE set emp_name=? where emp_id=?
52Employee Update Status=1
53Hibernate: delete from ADDRESS where emp_id=?
54Address Delete Status=1
55Hibernate: delete from EMPLOYEE where emp_id=?
56Employee Delete Status=1
57Hibernate: select sum(employee0_.emp_salary) as col_0_0_ from EMPLOYEE employee0_
58Sum of all Salaries= 600.0
59Hibernate: select employee0_.emp_name as col_0_0_, address1_.city as col_1_0_ from EMPLOYEE employee0_ inner join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id
60[Pankaj Kumar, San Jose]
61[David, Santa Clara]
62[Lisa, Bangalore]
63Hibernate: select employee0_.emp_name as col_0_0_, sum(employee0_.emp_salary) as col_1_0_, count(employee0_.emp_id) as col_2_0_ from EMPLOYEE employee0_ where employee0_.emp_name like '%i%' group by employee0_.emp_name
64[David, 200.0, 1]
65[Lisa, 300.0, 1]
66Hibernate: select employee0_.emp_id as emp_id1_1_, employee0_.emp_name as emp_name2_1_, employee0_.emp_salary as emp_sala3_1_ from EMPLOYEE employee0_ order by employee0_.emp_id desc
67ID Desc Order Employee::3,Bangalore
68ID Desc Order Employee::2,Santa Clara
69ID Desc Order Employee::1,San Jose
70May 22, 2014 1:55:38 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
71INFO: HHH000030: Cleaning up connection pool [jdbc:mysql://localhost/TestDB]

请注意,一旦执行了删除操作,进一步的操作将不会显示该记录数据(工资总和为600)。但是,我正在回滚事务,因此表中的数据将保持不变。更改代码以提交事务,它将反映在数据库表中。我不太喜欢使用HQL查询,因为如您所见,我们需要在代码中处理表映射。如果我们将使用Session删除Employee对象,它将从两个表中删除记录。您可以从下面的链接下载示例hql示例项目,并尝试更多示例。

下载Hibernate HQL Project

Published At
Categories with 技术
Tagged with
comments powered by Disqus