CyStack logo
  • Sản phẩm & Dịch vụ
  • Giải pháp
  • Bảng giá
  • Công ty
  • Tài liệu
Vi

vi

Mục lục

Trang chủBlogTìm hiểu Hibernate Named ...
Java

Tìm hiểu Hibernate Named Query – Khai báo, sử dụng và ví dụ code

6 phút đọc23/09/2025
CyStack Author
Bao Tran

Web Developer

0 lượt xem
Reading Time: 6 minutes

Chào mừng bạn đến với hướng dẫn ví dụ về Hibernate Named Query.

Hibernate Named Query

Trước đây, chúng ta đã thấy cách sử dụng Hibernate Query Language (HQL)và Native SQL Query trong Hibernate. Tuy nhiên, nếu có quá nhiều query, mã nguồn sẽ trở nên rối rắm vì các query bị phân tán khắp dự án.

Đó là lý do Hibernate cung cấp Named Query , cho phép chúng ta định nghĩa các query ở một vị trí tập trung, rồi sử dụng lại ở bất kỳ đâu trong code. Named Query có thể được tạo cho cả HQL lẫn Native SQL.

Hibernate Named Query

Hibernate Named Query (truy vấn đặt tên trong Hibernate) có thể được định nghĩa trong Hibernate mapping files hoặc thông qua JPA annotations như @NamedQuery@NamedNativeQuery.

Trong bài này, chúng ta sẽ tìm hiểu cả hai cách và cách sử dụng Hibernate Named Query trong một ứng dụng đơn giản. Chúng ta sẽ dùng lại các bảng cơ sở dữ liệu giống như trong ví dụ HQL, vì vậy bạn có thể tham khảo bài đó để lấy SQL script thiết lập cơ sở dữ liệu.

Trong ví dụ này, dự án sẽ sử dụng annotations cho Hibernate mapping. Tuy nhiên, chúng ta cũng sẽ tạo một số Named Query trong cả mapping files và entity bean classes.

Cấu trúc cuối cùng của dự án sẽ giống như hình dưới đây, và chúng ta sẽ tập trung chủ yếu vào các thành phần liên quan đến Hibernate Named Query.

Tệp cấu hình Hibernate dạng XML

hibernate.cfg.xml


  ">

	
		com.mysql.jdbc.Driver
		pankaj123
		jdbc:mysql://localhost/TestDB
		pankaj
		org.hibernate.dialect.MySQLDialect

		thread
		true

		
		
		
	

Chúng ta có một tệp Hibernate mapping chứa các HQL Named Query và Native SQL Named Query.

Tệp này có tên là named-queries.hbm.xml


">
	

	from Employee

	
		
	

	
		 :salary]]>
	
	
	
		
	
	
	
		
		
		
	

Phần tử query được dùng để khai báo HQL Named Query, còn phần tử sql-query được dùng cho Native SQL Named Query. Chúng ta có thể dùng phần tử return để khai báo entity mà result set sẽ được ánh xạ tới. return-join được sử dụng khi chúng ta thực hiện join nhiều bảng.

Khi khai báo Hibernate Named Query trong XML, nên sử dụng CDATA để đảm bảo nội dung query được xử lý như dữ liệu, nếu không thì các ký tự <> sẽ làm hỏng file mapping XML.

Hibernate Named Query với Annotation @NamedQuery

Chúng ta có hai model class là EmployeeAddress.

Các Named Query được định nghĩa trong class Address như dưới đây.

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;
	}
}

Chương trình kiểm thử Hibernate Named Query

Bây giờ, chúng ta sẽ viết một chương trình test để sử dụng tất cả các Hibernate Named Query đã định nghĩa ở trên.

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 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
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 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(); } }

Khi chúng ta chạy chương trình trên với dữ liệu kiểm thử hiện có, nó sẽ tạo ra kết quả đầu ra như sau.

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

Những điểm quan trọng về Hibernate Named Query

Một số điểm cần lưu ý về Hibernate Named Query:

  • Hibernate Named Query giúp gom các query lại ở một vị trí trung tâm, thay vì để chúng rải rác khắp mã nguồn.
  • Cú pháp của Hibernate Named Query sẽ được kiểm tra khi Hibernate SessionFactory được tạo, nhờ đó ứng dụng sẽ báo lỗi sớm nếu có sai sót trong Named Query.
  • Hibernate Named Query mang tính toàn cục. Nghĩa là một khi đã được định nghĩa, nó có thể được sử dụng ở bất kỳ đâu trong ứng dụng.
  • Một nhược điểm lớn của Named Query là khó debug, vì chúng ta phải tìm ra vị trí mà query được định nghĩa.

Về tác giả

Bao Tran
Bao TranWeb Developer

I’m passionate about web development and sharing my insights through articles, with over 8 years of experience. I hope these sharings inspire you and help build a strong web development community. @#@ Tôi đam mê phát triển web và chia sẻ những hiểu biết của mình thông qua các bài viết, với hơn 8 năm kinh nghiệm. Tôi hy vọng những chia sẻ này sẽ truyền cảm hứng cho các bạn và giúp xây dựng một cộng đồng phát triển web mạnh mẽ.

Cập nhật thông tin mới nhấtNhận các thông tin mới nhất về mối đe dọa, báo cáo an ninh mạng từ CyStack về hòm thư điện tử của bạn

Thảo luận (0)

Đăng nhập để thảo luận

Bài viết liên quan