欢迎来到Hibernate命名查询示例教程。我们了解了如何使用HQL。如果有很多查询,那么它们将导致代码混乱,因为所有的查询都将分散在整个项目中。这就是Hibernate提供命名查询 的原因,我们可以在中央位置定义它,并在代码中的任何位置使用它们。我们可以为HQL和Native SQL创建命名查询。
Hibernate命名查询
Hibernate Name Query可以在Hibernate映射文件中定义,也可以通过jpa注释
@NamedQuery
和@NamedNativeQuery
定义。今天,我们将研究这两种方法,以及如何在一个简单的应用程序中使用Hibernate命名查询。我们将使用与[HQLSQL)中相同的数据库表,因此您可以查看该帖子中的数据库设置Example](/community/tutorials/hibernate-query-language-hql-example-tutorial脚本。对于我们的Hibernate命名查询示例项目,我们将使用注解来进行Hibernate映射。但是,我们将在映射文件和实体Bean类中创建一些命名查询。我们最终的项目结构如下图所示,我们将主要关注与Hibernate命名查询相关的组件。
Hibernate配置XML
hibernate.cfg.xml
1<?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE hibernate-configuration SYSTEM "https://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
3<hibernate-configuration>
4 <session-factory>
5 <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
6 <property name="hibernate.connection.password">pankaj123</property>
7 <property name="hibernate.connection.url">jdbc:mysql://localhost/TestDB</property>
8 <property name="hibernate.connection.username">pankaj</property>
9 <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
10
11 <property name="hibernate.current_session_context_class">thread</property>
12 <property name="hibernate.show_sql">true</property>
13
14 <mapping class="com.journaldev.hibernate.model.Employee" />
15 <mapping class="com.journaldev.hibernate.model.Address" />
16 <mapping resource="named-queries.hbm.xml" />
17 </session-factory>
18</hibernate-configuration>
Hibernate命名查询XML
我们有一个Hibernate映射文件,其中只包含HQL命名查询和Native SQL命名查询。Name-quies.hbm.xml
1<?xml version="1.0"?>
2<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
3 "https://hibernate.org/dtd/hibernate-mapping-3.0.dtd">
4
5<hibernate-mapping>
6 <query name="HQL_GET_ALL_EMPLOYEE">from Employee</query>
7
8 <query name="HQL_GET_EMPLOYEE_BY_ID">
9 <![CDATA[from Employee where emp_id = :id]]>
10 </query>
11
12 <query name="HQL_GET_EMPLOYEE_BY_SALARY">
13 <![CDATA[from Employee where emp_salary > :salary]]>
14 </query>
15
16 <sql-query name="SQL_GET_ALL_EMPLOYEE">
17 <![CDATA[select emp_id, emp_name, emp_salary from Employee]]>
18 </sql-query>
19
20 <sql-query name="SQL_GET_ALL_EMP_ADDRESS">
21 <![CDATA[select {e.*}, {a.*} from Employee e join Address a ON e.emp_id=a.emp_id]]>
22 <return alias="e" class="com.journaldev.hibernate.model.Employee" />
23 <return-join alias="a" property="e.address"></return-join>
24 </sql-query>
25</hibernate-mapping>
Query 元素用于HQL命名查询,** SQL-Query** 元素用于原生SQL命名查询。我们可以使用** Return** 元素声明结果集要映射到的实体。** RETURN-JOIN** 用于我们有多个表的JOIN时。我们应该使用CDATA来声明我们的Hibernate命名查询,以确保它被视为数据,否则
Hibernate命名查询@NamedQuery注释
我们有两个模型类-Employee
和Address
。我们在Address
类中定义了名称查询,如下所示。
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.NamedNativeQueries;
8import javax.persistence.NamedNativeQuery;
9import javax.persistence.NamedQueries;
10import javax.persistence.NamedQuery;
11import javax.persistence.OneToOne;
12import javax.persistence.PrimaryKeyJoinColumn;
13import javax.persistence.Table;
14
15import org.hibernate.annotations.GenericGenerator;
16import org.hibernate.annotations.Parameter;
17
18@Entity
19@Table(name = "ADDRESS")
20@NamedQueries({ @NamedQuery(name = "@HQL_GET_ALL_ADDRESS",
21 query = "from Address") })
22@NamedNativeQueries({ @NamedNativeQuery(name = "@SQL_GET_ALL_ADDRESS",
23 query = "select emp_id, address_line1, city, zipcode from Address") })
24public class Address {
25
26 @Id
27 @Column(name = "emp_id", unique = true, nullable = false)
28 @GeneratedValue(generator = "gen")
29 @GenericGenerator(name = "gen", strategy = "foreign", parameters = { @Parameter(name = "property", value = "employee") })
30 private long id;
31
32 @Column(name = "address_line1")
33 private String addressLine1;
34
35 @Column(name = "zipcode")
36 private String zipcode;
37
38 @Column(name = "city")
39 private String city;
40
41 @OneToOne
42 @PrimaryKeyJoinColumn
43 private Employee employee;
44
45 public long getId() {
46 return id;
47 }
48
49 public void setId(long id) {
50 this.id = id;
51 }
52
53 public String getAddressLine1() {
54 return addressLine1;
55 }
56
57 public void setAddressLine1(String addressLine1) {
58 this.addressLine1 = addressLine1;
59 }
60
61 public String getZipcode() {
62 return zipcode;
63 }
64
65 public void setZipcode(String zipcode) {
66 this.zipcode = zipcode;
67 }
68
69 public String getCity() {
70 return city;
71 }
72
73 public void setCity(String city) {
74 this.city = city;
75 }
76
77 public Employee getEmployee() {
78 return employee;
79 }
80
81 public void setEmployee(Employee employee) {
82 this.employee = employee;
83 }
84
85 @Override
86 public String toString() {
87 return "AddressLine1= " + addressLine1 + ", City=" + city
88 + ", Zipcode=" + zipcode;
89 }
90}
Hibernate命名查询测试程序
让我们编写一个测试程序来使用上面定义的所有Hibernate命名查询。
1package com.journaldev.hibernate.main;
2
3import java.util.List;
4
5import org.hibernate.Query;
6import org.hibernate.Session;
7import org.hibernate.SessionFactory;
8import org.hibernate.Transaction;
9
10import com.journaldev.hibernate.model.Address;
11import com.journaldev.hibernate.model.Employee;
12import com.journaldev.hibernate.util.HibernateUtil;
13
14public class HibernateNamedQueryExample {
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 Transaction tx = session.beginTransaction();
23
24 //HQL Named Query Example
25 Query query = session.getNamedQuery("HQL_GET_ALL_EMPLOYEE");
26 List<Employee> empList = query.list();
27 for (Employee emp : empList) {
28 System.out.println("List of Employees::" + emp.getId() + ","
29 + emp.getAddress().getCity());
30 }
31
32 query = session.getNamedQuery("HQL_GET_EMPLOYEE_BY_ID");
33 query.setInteger("id", 2);
34 Employee emp = (Employee) query.uniqueResult();
35 System.out.println("Employee Name=" + emp.getName() + ", City="
36 + emp.getAddress().getCity());
37
38 query = session.getNamedQuery("HQL_GET_EMPLOYEE_BY_SALARY");
39 query.setInteger("salary", 200);
40 empList = query.list();
41 for (Employee emp1 : empList) {
42 System.out.println("List of Employees::" + emp1.getId() + ","
43 + emp1.getSalary());
44 }
45
46 query = session.getNamedQuery("@HQL_GET_ALL_ADDRESS");
47 List<Address> addressList = query.list();
48 for (Address addr : addressList) {
49 System.out.println("List of Address::" + addr.getId() + "::"
50 + addr.getZipcode() + "::" + addr.getEmployee().getName());
51 }
52
53 //Native SQL Named Query Example
54 query = session.getNamedQuery("@SQL_GET_ALL_ADDRESS");
55 List<Object[]> addressObjArray = query.list();
56 for(Object[] row : addressObjArray){
57 for(Object obj : row){
58 System.out.print(obj + "::");
59 }
60 System.out.println("\n");
61 }
62
63 query = session.getNamedQuery("SQL_GET_ALL_EMP_ADDRESS");
64 addressObjArray = query.list();
65 for(Object[] row : addressObjArray){
66 Employee e = (Employee) row[0];
67 System.out.println("Employee Info::"+e);
68 Address a = (Address) row[1];
69 System.out.println("Address Info::"+a);
70 }
71 // rolling back to save the test data
72 tx.commit();
73
74 // closing hibernate resources
75 sessionFactory.close();
76 }
77
78}
当我们用我们已有的测试数据执行上面的程序时,它会产生以下输出。
1Hibernate: 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_
2Hibernate: 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=?
3Hibernate: 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=?
4Hibernate: 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=?
5Hibernate: 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=?
6List of Employees::1,San Jose
7List of Employees::2,Santa Clara
8List of Employees::3,Bangalore
9List of Employees::4,New Delhi
10Hibernate: 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 emp_id=?
11Employee Name=David, City=Santa Clara
12Hibernate: 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 emp_salary>?
13List of Employees::3,300.0
14List of Employees::4,400.0
15Hibernate: select address0_.emp_id as emp_id1_0_, address0_.address_line1 as address_2_0_, address0_.city as city3_0_, address0_.zipcode as zipcode4_0_ from ADDRESS address0_
16List of Address::1::95129::Pankaj
17List of Address::2::95051::David
18List of Address::3::560100::Lisa
19List of Address::4::100100::Jack
20Hibernate: select emp_id, address_line1, city, zipcode from Address
211::Albany Dr::San Jose::95129::
22
232::Arques Ave::Santa Clara::95051::
24
253::BTM 1st Stage::Bangalore::560100::
26
274::City Centre::New Delhi::100100::
28
29Hibernate: select e.emp_id as emp_id1_1_0_, e.emp_name as emp_name2_1_0_, e.emp_salary as emp_sala3_1_0_, a.emp_id as emp_id1_0_1_, a.address_line1 as address_2_0_1_, a.city as city3_0_1_, a.zipcode as zipcode4_0_1_ from Employee e join Address a ON e.emp_id=a.emp_id
30Employee Info::Id= 1, Name= Pankaj, Salary= 100.0, {Address= AddressLine1= Albany Dr, City=San Jose, Zipcode=95129}
31Address Info::AddressLine1= Albany Dr, City=San Jose, Zipcode=95129
32Employee Info::Id= 2, Name= David, Salary= 200.0, {Address= AddressLine1= Arques Ave, City=Santa Clara, Zipcode=95051}
33Address Info::AddressLine1= Arques Ave, City=Santa Clara, Zipcode=95051
34Employee Info::Id= 3, Name= Lisa, Salary= 300.0, {Address= AddressLine1= BTM 1st Stage, City=Bangalore, Zipcode=560100}
35Address Info::AddressLine1= BTM 1st Stage, City=Bangalore, Zipcode=560100
36Employee Info::Id= 4, Name= Jack, Salary= 400.0, {Address= AddressLine1= City Centre, City=New Delhi, Zipcode=100100}
37Address Info::AddressLine1= City Centre, City=New Delhi, Zipcode=100100
Hibernate命名查询要点
Hibernate命名查询的几个要点是;
1.Hibernate命名查询帮助我们在中央位置对查询进行分组,而不是让它们分散在代码中。 2.在创建Hibernate会话工厂时检查Hibernate命名查询语法,从而使应用程序在命名查询出现错误的情况下快速失败。 3.Hibernate命名查询是全局的,这意味着一旦定义,它就可以在整个应用程序中使用。 4.命名查询的一大缺点是很难调试,因为我们需要找出它定义的位置。
这就是Hibernate命名查询示例,您可以从下面的链接下载示例项目。