Hibernate 命名查询示例 - @NamedQuery

欢迎来到Hibernate命名查询示例教程。我们了解了如何使用HQL。如果有很多查询,那么它们将导致代码混乱,因为所有的查询都将分散在整个项目中。这就是Hibernate提供命名查询 的原因,我们可以在中央位置定义它,并在代码中的任何位置使用它们。我们可以为HQL和Native SQL创建命名查询。

Hibernate命名查询

Hibernate Name Query,@NamedQueryHibernate Name Query可以在Hibernate映射文件中定义,也可以通过jpa注释@NamedQuery@NamedNativeQuery定义。今天,我们将研究这两种方法,以及如何在一个简单的应用程序中使用Hibernate命名查询。我们将使用与[HQLSQL)中相同的数据库表,因此您可以查看该帖子中的数据库设置Example](/community/tutorials/hibernate-query-language-hql-example-tutorial脚本。对于我们的Hibernate命名查询示例项目,我们将使用注解来进行Hibernate映射。但是,我们将在映射文件和实体Bean类中创建一些命名查询。我们最终的项目结构如下图所示,我们将主要关注与Hibernate命名查询相关的组件。Hibernate命名查询,@NamedQuery

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命名查询,以确保它被视为数据,否则sings会弄乱我们的映射XML文件。

Hibernate命名查询@NamedQuery注释

我们有两个模型类-EmployeeAddress。我们在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命名查询示例,您可以从下面的链接下载示例项目。

下载Hibernate命名查询Project

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