مثال استعلام مسمى هيبرنيت – @NamedQuery

مرحبا بكم في الدرس التعليمي لمثال استعلام Hibernate الذي يحمل اسمًا. لقد رأينا كيف يمكننا استخدام HQL واستعلام SQL الأصلي في Hibernate. إذا كان هناك الكثير من الاستعلامات، فسوف يسبب ذلك فوضى في الكود لأن جميع الاستعلامات ستكون مبعثرة في جميع أنحاء المشروع. هذا هو السبب في أن Hibernate يوفر استعلام بالاسم يمكننا تعريفه في موقع مركزي واستخدامه في أي مكان في الرمز. يمكننا إنشاء استعلامات تحمل اسمًا لكل من HQL و SQL الأصلي.

استعلام Hibernate الذي يحمل اسمًا

يمكن تحديد استعلام Hibernate Named Query في ملفات تعيين Hibernate أو من خلال استخدام تعليقات JPA @NamedQuery و @NamedNativeQuery. اليوم سننظر في كل منها وكيفية استخدام استعلام hibernate named query في تطبيق بسيط. سنستخدم نفس جداول قاعدة البيانات كما في مثال HQL، حتى تتمكن من التحقق من ذلك المنشور لنص البرنامج النصي لإعداد قاعدة البيانات. بالنسبة لمشروعنا المثالي لاستعلام hibernate named query، سنستخدم التعليقات لتعيين Hibernate. ومع ذلك، سنقوم بإنشاء بعض الاستعلامات المسماة في كل من ملفات التعيين وفي فئات كائن الكيان. تبدو هيكل المشروع النهائي لدينا كالصورة أدناه، وسنركز بشكل رئيسي على المكونات المتعلقة بـ Hibernate Named Query.

Hibernate Configuration 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، يحتوي على استعلامات مسماة HQL فقط واستعلامات مسماة SQL الأصلية. 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 للاستعلامات المسماة HQL ويتم استخدام عنصر sql-query للاستعلامات المسماة بSQL الأصلية. يمكننا استخدام عنصر return لتعريف الكيان الذي سيتم تعيين النتيجة إليه. يتم استخدام return-join عندما يكون لدينا انضمام لجداول متعددة. يجب علينا استخدام CDATA لتعريف استعلام Hibernate المسمى لدينا للتأكد من أنه يتم التعامل معه كبيانات، وإلا فإن علامات < و > ستؤثر سلباً على ملف التعيين XML الخاص بنا.

استعلام Hibernate المسمىالتعليق @NamedQuery

لدينا فئتان نموذجيتان – 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 المسمى

\begin{Arabic}
لنكتب برنامج اختبار لاستخدام جميع الاستعلامات المسماة في 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) {

		// العمل التحضيري
		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		Session session = sessionFactory.getCurrentSession();
		Transaction tx = session.beginTransaction();

		// مثال على HQL Named Query
		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 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); } // التراجع لحفظ بيانات الاختبار tx.commit(); // إغلاق موارد Hibernate sessionFactory.close(); } }

عند تنفيذ البرنامج أعلاه مع البيانات الاختبارية التي نملكها ، يتم إنتاج الإخراج التالي.

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 Named Query

بعض النقاط المهمة حول Hibernate Named Query هي:

  1. تساعدنا Hibernate Named Query في تجميع الاستعلامات في مكان مركزي بدلاً من السماح لها بالتشتت في جميع أنحاء الشيفرة.
  2. يتم فحص بنية Hibernate Named Query عند إنشاء مصنع جلسات Hibernate ، مما يجعل التطبيق يفشل بشكل سريع في حالة وجود أي خطأ في الاستعلامات المسماة.
  3. يعد Hibernate Named Query عالميًا ، مما يعني أنه بمجرد تعريفه يمكن استخدامه في جميع أنحاء التطبيق.
  4. إحدى المساوئ الرئيسية للاستعلام المسمى هي أنه من الصعب تصحيحه ، لأنه يتعين علينا البحث عن الموقع الذي يتم فيه تعريفه.

هذا كل شيء بالنسبة لمثال Hibernate Named Query ، يمكنك تنزيل المشروع عينة من الرابط أدناه.

تنزيل مشروع Hibernate Named Query
\end{Arabic}

Source:
https://www.digitalocean.com/community/tutorials/hibernate-named-query-example-namedquery