Hibernate - Đánh chặn

Như bạn đã biết rằng trong Hibernate, một đối tượng sẽ được tạo và tồn tại. Khi đối tượng đã được thay đổi, nó phải được lưu trở lại cơ sở dữ liệu. Quá trình này tiếp tục cho đến lần tiếp theo đối tượng cần thiết và nó sẽ được tải từ kho lưu trữ liên tục.

Do đó, một đối tượng trải qua các giai đoạn khác nhau trong vòng đời của nó và Interceptor Interfacecung cấp các phương thức, có thể được gọi ở các giai đoạn khác nhau để thực hiện một số tác vụ được yêu cầu. Các phương thức này là các lệnh gọi lại từ phiên đến ứng dụng, cho phép ứng dụng kiểm tra và / hoặc thao tác các thuộc tính của một đối tượng liên tục trước khi nó được lưu, cập nhật, xóa hoặc tải. Sau đây là danh sách tất cả các phương thức có sẵn trong giao diện Interceptor:

Sr.No. Phương pháp & Mô tả
1

findDirty()

Phương thức này được gọi khi flush() phương thức được gọi trên một đối tượng Session.

2

instantiate()

Phương thức này được gọi khi một lớp kiên trì được khởi tạo.

3

isUnsaved()

Phương thức này được gọi khi một đối tượng được chuyển đến saveOrUpdate() phương pháp/

4

onDelete()

Phương thức này được gọi trước khi một đối tượng bị xóa.

5

onFlushDirty()

Phương thức này được gọi khi Hibernate phát hiện thấy một đối tượng bị bẩn (tức là đã được thay đổi) trong quá trình xả tức là hoạt động cập nhật.

6

onLoad()

Phương thức này được gọi trước khi một đối tượng được khởi tạo.

7

onSave()

Phương thức này được gọi trước khi một đối tượng được lưu.

số 8

postFlush()

Phương thức này được gọi sau khi một lần xả đã xảy ra và một đối tượng đã được cập nhật trong bộ nhớ.

9

preFlush()

Phương thức này được gọi trước một lần xả.

Hibernate Interceptor cho chúng ta toàn quyền kiểm soát cách một đối tượng sẽ trông như thế nào đối với cả ứng dụng và cơ sở dữ liệu.

Làm thế nào để sử dụng Interceptors?

Để xây dựng một thiết bị đánh chặn, bạn có thể triển khai Interceptor lớp học trực tiếp hoặc mở rộng EmptyInterceptorlớp học. Sau đây sẽ là các bước đơn giản để sử dụng chức năng Hibernate Interceptor.

Tạo thiết bị đánh chặn

Chúng tôi sẽ mở rộng EmptyInterceptor trong ví dụ của chúng tôi, nơi phương thức của Interceptor sẽ được gọi tự động khi Employeeđối tượng được tạo và cập nhật. Bạn có thể triển khai nhiều phương pháp hơn theo yêu cầu của bạn.

import java.io.Serializable;
import java.util.Date;
import java.util.Iterator;

import org.hibernate.EmptyInterceptor;
import org.hibernate.Transaction;
import org.hibernate.type.Type;

public class MyInterceptor extends EmptyInterceptor {
   private int updates;
   private int creates;
   private int loads;

   public void onDelete(Object entity, Serializable id,
      Object[] state, String[] propertyNames, Type[] types) {
       // do nothing
   }

   // This method is called when Employee object gets updated.
   public boolean onFlushDirty(Object entity, Serializable id,
      Object[] currentState, Object[] previousState, String[] propertyNames,
      Type[] types) {
         if ( entity instanceof Employee ) {
            System.out.println("Update Operation");
            return true; 
         }
         return false;
   }
	
   public boolean onLoad(Object entity, Serializable id,
      Object[] state, String[] propertyNames, Type[] types) {
         // do nothing
         return true;
   }
   
   // This method is called when Employee object gets created.
   public boolean onSave(Object entity, Serializable id,
      Object[] state, String[] propertyNames, Type[] types) {
         if ( entity instanceof Employee ) {
            System.out.println("Create Operation");
            return true; 
         }
         return false;
   }
   
   //called before commit into database
   public void preFlush(Iterator iterator) {
      System.out.println("preFlush");
   }
   
   //called after committed into database
   public void postFlush(Iterator iterator) {
      System.out.println("postFlush");
   }
}

Tạo lớp học POJO

Bây giờ, chúng ta hãy sửa đổi một chút ví dụ đầu tiên của chúng ta, nơi chúng ta sử dụng bảng EMPLOYEE và lớp Nhân viên để chơi với -

public class Employee {
   private int id;
   private String firstName; 
   private String lastName;   
   private int salary;  

   public Employee() {}
   
   public Employee(String fname, String lname, int salary) {
      this.firstName = fname;
      this.lastName = lname;
      this.salary = salary;
   }
   
   public int getId() {
      return id;
   }
   
   public void setId( int id ) {
      this.id = id;
   }
   
   public String getFirstName() {
      return firstName;
   }
   
   public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
   
   public String getLastName() {
      return lastName;
   }
   
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   
   public int getSalary() {
      return salary;
   }
   
   public void setSalary( int salary ) {
      this.salary = salary;
   }
}

Tạo bảng cơ sở dữ liệu

Bước thứ hai sẽ là tạo các bảng trong cơ sở dữ liệu của bạn. Sẽ có một bảng tương ứng với mỗi đối tượng, bạn sẵn sàng cung cấp tính bền bỉ. Hãy xem xét các đối tượng được giải thích ở trên, cần được lưu trữ và truy xuất vào bảng RDBMS sau:

create table EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

Tạo tệp cấu hình ánh xạ

Bước này là tạo một tệp ánh xạ hướng dẫn Hibernate - cách ánh xạ lớp hoặc các lớp đã xác định vào bảng cơ sở dữ liệu.

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 

<hibernate-mapping>
   <class name = "Employee" table = "EMPLOYEE">
      
      <meta attribute = "class-description">
         This class contains the employee detail. 
      </meta>
      
      <id name = "id" type = "int" column = "id">
         <generator class="native"/>
      </id>
      
      <property name = "firstName" column = "first_name" type = "string"/>
      <property name = "lastName" column = "last_name" type = "string"/>
      <property name = "salary" column = "salary" type = "int"/>
      
   </class>
</hibernate-mapping>

Tạo lớp ứng dụng

Cuối cùng, chúng ta sẽ tạo lớp ứng dụng của mình với phương thức main () để chạy ứng dụng. Ở đây, cần lưu ý rằng trong khi tạo đối tượng phiên, chúng ta đã sử dụng lớp Interceptor của mình làm đối số.

import java.util.List; 
import java.util.Date;
import java.util.Iterator; 
 
import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {
   private static SessionFactory factory; 
   public static void main(String[] args) {
      
      try {
         factory = new Configuration().configure().buildSessionFactory();
      } catch (Throwable ex) { 
         System.err.println("Failed to create sessionFactory object." + ex);
         throw new ExceptionInInitializerError(ex); 
      }

      ManageEmployee ME = new ManageEmployee();

      /* Add few employee records in database */
      Integer empID1 = ME.addEmployee("Zara", "Ali", 1000);
      Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
      Integer empID3 = ME.addEmployee("John", "Paul", 10000);

      /* List down all the employees */
      ME.listEmployees();

      /* Update employee's records */
      ME.updateEmployee(empID1, 5000);

      /* Delete an employee from the database */
      ME.deleteEmployee(empID2);

      /* List down new list of the employees */
      ME.listEmployees();
   }
   
   /* Method to CREATE an employee in the database */
   public Integer addEmployee(String fname, String lname, int salary){
      Session session = factory.openSession( new MyInterceptor() );
      Transaction tx = null;
      Integer employeeID = null;
      
      try {
         tx = session.beginTransaction();
         Employee employee = new Employee(fname, lname, salary);
         employeeID = (Integer) session.save(employee); 
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
      return employeeID;
   }
   
   /* Method to  READ all the employees */
   public void listEmployees( ){
      Session session = factory.openSession( new MyInterceptor() );
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         List employees = session.createQuery("FROM Employee").list(); 
         for (Iterator iterator = employees.iterator(); iterator.hasNext();){
            Employee employee = (Employee) iterator.next(); 
            System.out.print("First Name: " + employee.getFirstName()); 
            System.out.print("  Last Name: " + employee.getLastName()); 
            System.out.println("  Salary: " + employee.getSalary()); 
         }
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
   
   /* Method to UPDATE salary for an employee */
   public void updateEmployee(Integer EmployeeID, int salary ){
      Session session = factory.openSession( new MyInterceptor() );
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         Employee employee = (Employee)session.get(Employee.class, EmployeeID); 
         employee.setSalary( salary );
		 session.update(employee); 
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
   
   /* Method to DELETE an employee from the records */
   public void deleteEmployee(Integer EmployeeID){
      Session session = factory.openSession( new MyInterceptor() );
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         Employee employee = (Employee)session.get(Employee.class, EmployeeID); 
         session.delete(employee); 
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
}

Biên dịch và Thực hiện

Dưới đây là các bước để biên dịch và chạy ứng dụng được đề cập ở trên. Đảm bảo rằng bạn đã đặt PATH và CLASSPATH thích hợp trước khi tiếp tục biên dịch và thực thi.

  • Tạo tệp cấu hình hibernate.cfg.xml như được giải thích trong chương cấu hình.

  • Tạo tệp ánh xạ Employee.hbm.xml như hình trên.

  • Tạo tệp nguồn Employee.java như hình trên và biên dịch nó.

  • Tạo tệp nguồn MyInterceptor.java như được hiển thị ở trên và biên dịch nó.

  • Tạo tệp nguồn ManageEaffee.java như hình trên và biên dịch nó.

  • Thực thi lệnh nhị phân ManageE Jobee để chạy chương trình.

Bạn sẽ nhận được kết quả sau và các bản ghi sẽ được tạo trong bảng NHÂN VIÊN.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

Create Operation
preFlush
postFlush
Create Operation
preFlush
postFlush
Create Operation
preFlush
postFlush
First Name: Zara  Last Name: Ali  Salary: 1000
First Name: Daisy  Last Name: Das  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000
preFlush
postFlush
preFlush
Update Operation
postFlush
preFlush
postFlush
First Name: Zara  Last Name: Ali  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000
preFlush
postFlush

Nếu bạn kiểm tra bảng EMPLOYEE của mình, bảng này sẽ có các bản ghi sau:

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 29 | Zara       | Ali       |   5000 |
| 31 | John       | Paul      |  10000 |
+----+------------+-----------+--------+
2 rows in set (0.00 sec
mysql>