namedquery
Welcome to Hibernate Named Query Example Tutorial. We saw how we can use HQL and Native SQL Query in Hibernate. If there are a lot of queries, then they will cause a code mess because all the queries will be scattered throughout the project. That’s why Hibernate provides Named Query that we can define at a central location and use them anywhere in the code. We can created named queries for both HQL and Native SQL.
欢迎使用Hibernate命名查询示例教程。 我们看到了如何在Hibernate中使用HQL和本机SQL查询 。 如果有很多查询,那么它们将导致代码混乱,因为所有查询都将分散在整个项目中。 这就是为什么Hibernate提供命名查询的原因,我们可以在中央位置进行定义并在代码中的任何位置使用它们。 我们可以为HQL和本机SQL创建命名查询。
Hibernate命名查询 (Hibernate Named Query)
Hibernate Named Query can be defined in Hibernate mapping files or through the use of JPA annotations @NamedQuery
and @NamedNativeQuery
. Today we will look into both of them and how to use hibernate named query in a simple application.
可以在Hibernate映射文件中定义Hibernate命名查询,也可以使用JPA批注@NamedQuery
和@NamedNativeQuery
。 今天,我们将研究它们两者以及如何在简单的应用程序中使用Hibernate命名查询。
We will use the same database tables as in HQL Example, so you can check that post for database setup sql script.
我们将使用与HQL Example中相同的数据库表,因此您可以检查该帖子以获取数据库设置sql脚本。
For our hibernate named query example project, we will use annotations for hibernate mapping. However we will create some named queries in both mapping files and in entity bean classes. Our final project structure looks like below image, we will focus mainly on the components related to Hibernate Named Query.
对于我们的Hibernate命名查询示例项目,我们将使用注释进行Hibernate映射。 但是,我们将在映射文件和实体Bean类中创建一些命名查询。 我们的最终项目结构如下图所示,我们将主要关注与Hibernate Named Query相关的组件。
Hibernate配置XML (Hibernate Configuration XML)
hibernate.cfg.xml
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration SYSTEM "https://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">pankaj123</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/TestDB</property>
<property name="hibernate.connection.username">pankaj</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.show_sql">true</property>
<mapping class="com.journaldev.hibernate.model.Employee" />
<mapping class="com.journaldev.hibernate.model.Address" />
<mapping resource="named-queries.hbm.xml" />
</session-factory>
</hibernate-configuration>
Hibernate命名查询XML (Hibernate Named Query XML)
We have a hibernate mapping file, that contains only HQL named queries and Native SQL named queries.
我们有一个Hibernate映射文件,该文件仅包含HQL命名查询和Native SQL命名查询。
named-queries.hbm.xml
named-queries.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<query name="HQL_GET_ALL_EMPLOYEE">from Employee</query>
<query name="HQL_GET_EMPLOYEE_BY_ID">
<![CDATA[from Employee where emp_id = :id]]>
</query>
<query name="HQL_GET_EMPLOYEE_BY_SALARY">
<![CDATA[from Employee where emp_salary > :salary]]>
</query>
<sql-query name="SQL_GET_ALL_EMPLOYEE">
<![CDATA[select emp_id, emp_name, emp_salary from Employee]]>
</sql-query>
<sql-query name="SQL_GET_ALL_EMP_ADDRESS">
<![CDATA[select {e.*}, {a.*} from Employee e join Address a ON e.emp_id=a.emp_id]]>
<return alias="e" class="com.journaldev.hibernate.model.Employee" />
<return-join alias="a" property="e.address"></return-join>
</sql-query>
</hibernate-mapping>
query element is used for HQL named queries and sql-query element is used for native sql named queries. We can use return element for declaring the entity to which resultset will be mapped. return-join is used when we have join of multiple tables.
query元素用于HQL命名查询,而sql-query元素用于本机sql命名查询。 我们可以使用return元素声明将结果集映射到的实体。 当我们有多个表的联接时,使用return-join 。
We should use CDATA to declare our hibernate named query to make sure it’s treated as data, otherwise < and > sings will mess up our mapping XML file.
我们应该使用CDATA声明我们的Hibernate命名查询,以确保将其视为数据,否则<和>唱歌会弄乱我们的映射XML文件。
Hibernate命名查询@NamedQuery注释 (Hibernate Named Query @NamedQuery Annotation)
We have two model classes – Employee
and Address
. We have defined names queries in Address
class as below.
我们有两个模型类Employee
和Address
。 我们在Address
类中定义了名称查询,如下所示。
package com.journaldev.hibernate.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
@Entity
@Table(name = "ADDRESS")
@NamedQueries({ @NamedQuery(name = "@HQL_GET_ALL_ADDRESS",
query = "from Address") })
@NamedNativeQueries({ @NamedNativeQuery(name = "@SQL_GET_ALL_ADDRESS",
query = "select emp_id, address_line1, city, zipcode from Address") })
public class Address {
@Id
@Column(name = "emp_id", unique = true, nullable = false)
@GeneratedValue(generator = "gen")
@GenericGenerator(name = "gen", strategy = "foreign", parameters = { @Parameter(name = "property", value = "employee") })
private long id;
@Column(name = "address_line1")
private String addressLine1;
@Column(name = "zipcode")
private String zipcode;
@Column(name = "city")
private String city;
@OneToOne
@PrimaryKeyJoinColumn
private Employee employee;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getAddressLine1() {
return addressLine1;
}
public void setAddressLine1(String addressLine1) {
this.addressLine1 = addressLine1;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
@Override
public String toString() {
return "AddressLine1= " + addressLine1 + ", City=" + city
+ ", Zipcode=" + zipcode;
}
}
Hibernate命名查询测试程序 (Hibernate Named Query Test Program)
Let’s write a test program to use all the hibernate named queries defined above.
让我们编写一个测试程序来使用上面定义的所有Hibernate命名查询。
package com.journaldev.hibernate.main;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.journaldev.hibernate.model.Address;
import com.journaldev.hibernate.model.Employee;
import com.journaldev.hibernate.util.HibernateUtil;
public class HibernateNamedQueryExample {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
// Prep work
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
//HQL Named Query Example
Query query = session.getNamedQuery("HQL_GET_ALL_EMPLOYEE");
List<Employee> empList = query.list();
for (Employee emp : empList) {
System.out.println("List of Employees::" + emp.getId() + ","
+ emp.getAddress().getCity());
}
query = session.getNamedQuery("HQL_GET_EMPLOYEE_BY_ID");
query.setInteger("id", 2);
Employee emp = (Employee) query.uniqueResult();
System.out.println("Employee Name=" + emp.getName() + ", City="
+ emp.getAddress().getCity());
query = session.getNamedQuery("HQL_GET_EMPLOYEE_BY_SALARY");
query.setInteger("salary", 200);
empList = query.list();
for (Employee emp1 : empList) {
System.out.println("List of Employees::" + emp1.getId() + ","
+ emp1.getSalary());
}
query = session.getNamedQuery("@HQL_GET_ALL_ADDRESS");
List<Address> addressList = query.list();
for (Address addr : addressList) {
System.out.println("List of Address::" + addr.getId() + "::"
+ addr.getZipcode() + "::" + addr.getEmployee().getName());
}
//Native SQL Named Query Example
query = session.getNamedQuery("@SQL_GET_ALL_ADDRESS");
List<Object[]> addressObjArray = query.list();
for(Object[] row : addressObjArray){
for(Object obj : row){
System.out.print(obj + "::");
}
System.out.println("\n");
}
query = session.getNamedQuery("SQL_GET_ALL_EMP_ADDRESS");
addressObjArray = query.list();
for(Object[] row : addressObjArray){
Employee e = (Employee) row[0];
System.out.println("Employee Info::"+e);
Address a = (Address) row[1];
System.out.println("Address Info::"+a);
}
// rolling back to save the test data
tx.commit();
// closing hibernate resources
sessionFactory.close();
}
}
When we execute above program with test data we have, it produces following output.
当我们使用测试数据执行上述程序时,将产生以下输出。
Hibernate: 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_
Hibernate: 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=?
Hibernate: 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=?
Hibernate: 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=?
Hibernate: 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=?
List of Employees::1,San Jose
List of Employees::2,Santa Clara
List of Employees::3,Bangalore
List of Employees::4,New Delhi
Hibernate: 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=?
Employee Name=David, City=Santa Clara
Hibernate: 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>?
List of Employees::3,300.0
List of Employees::4,400.0
Hibernate: 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_
List of Address::1::95129::Pankaj
List of Address::2::95051::David
List of Address::3::560100::Lisa
List of Address::4::100100::Jack
Hibernate: select emp_id, address_line1, city, zipcode from Address
1::Albany Dr::San Jose::95129::
2::Arques Ave::Santa Clara::95051::
3::BTM 1st Stage::Bangalore::560100::
4::City Centre::New Delhi::100100::
Hibernate: 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
Employee Info::Id= 1, Name= Pankaj, Salary= 100.0, {Address= AddressLine1= Albany Dr, City=San Jose, Zipcode=95129}
Address Info::AddressLine1= Albany Dr, City=San Jose, Zipcode=95129
Employee Info::Id= 2, Name= David, Salary= 200.0, {Address= AddressLine1= Arques Ave, City=Santa Clara, Zipcode=95051}
Address Info::AddressLine1= Arques Ave, City=Santa Clara, Zipcode=95051
Employee Info::Id= 3, Name= Lisa, Salary= 300.0, {Address= AddressLine1= BTM 1st Stage, City=Bangalore, Zipcode=560100}
Address Info::AddressLine1= BTM 1st Stage, City=Bangalore, Zipcode=560100
Employee Info::Id= 4, Name= Jack, Salary= 400.0, {Address= AddressLine1= City Centre, City=New Delhi, Zipcode=100100}
Address Info::AddressLine1= City Centre, City=New Delhi, Zipcode=100100
Hibernate命名查询要点 (Hibernate Named Query Important Points)
Few important points about Hibernate Named Query are;
关于Hibernate命名查询的几个要点是:
- Hibernate Named Query helps us in grouping queries at a central location rather than letting them scattered all over the code. Hibernate命名查询可帮助我们在中央位置对查询进行分组,而不是让它们分散在整个代码中。
- Hibernate Named Query syntax is checked when the hibernate session factory is created, thus making the application fail fast in case of any error in the named queries. 创建Hibernate会话工厂时,将检查“Hibernate命名查询”语法,从而使应用程序在命名查询中发生任何错误的情况下快速失败。
- Hibernate Named Query is global, means once defined it can be used throughout the application. Hibernate命名查询是全局的,这意味着一旦定义,它就可以在整个应用程序中使用。
- One of the major disadvantage of Named query is that it’s hard to debug, because we need to find out the location where it’s defined. 命名查询的主要缺点之一是难以调试,因为我们需要找出定义它的位置。
That’s all for the Hibernate Named Query Example, you can download the sample project from below link.
这就是“ Hibernate命名查询示例”的全部内容,您可以从下面的链接下载示例项目。
翻译自: https://www.journaldev.com/3451/hibernate-named-query-example-namedquery
namedquery