11/08/2018, 18:56

Interceptor trong Hibernate

Batch processing trong Hibernate Như bạn đã biết được rằng trong Hibernate, một đối tượng sẽ được tạo ra và tồn tại. Một 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 khi đối tượng tiếp theo được yêu cầu, và nó sẽ được tải từ ...

Batch processing trong Hibernate

Như bạn đã biết được rằng trong Hibernate, một đối tượng sẽ được tạo ra và tồn tại. Một 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 khi đối tượng tiếp theo được yêu cầu, và nó sẽ được tải từ các persistent store.

Do đó, một đối tượng đi qua các giai đoạn khác nhau trong vòng đời của nó. Giao tiếp Interceptor trong Hibernate cung 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ố nhiệm vụ được yêu cầu. Các phương thức này là gọi lại từ session tới ứ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 persistent trước khi nó được lưu, cập nhật, xóa hoặc nạp. Sau đây là danh sách tất cả các phương thức có sẵn trong Interceptor Interface:

No. Phương thức và mô tả
1 findDirty()

Phương thức này được gọi khi phương thức flush() đượ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 persistent được khởi tạo.

3 isUnsaved()

Phương thức này được gọi khi một đối tượng được truyền vào phương thức saveOrUpdate() /

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 ra rằng một đối tượng là dirty(tức là đã được thay đổi) trong quá trình flush nghĩa là thao tác update.

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.

8 postFlush()

Phương thức này được gọi sau khi flush và một đối tượng đã được update trong bộ nhớ.

9 preFlush()

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

Hibernate Interceptor cho phép chúng ta kiểm soát toàn diện đối tượng trong cả ứng dụng và cơ sở dữ liệu.

Ví dụ về Interceptor trong Hibernate

Để xây dựng một interceptor bạn có thể impliments lớp Interceptor trực tiếp hoặc extents lớp EmptyInterceptor. Sau đây là các bước đơn giản để sử dụng chức năng Interceptor trong Hibernate.

Tạo các Interceptor

Tạo lớp MyInterceptor kế thừa EmptyInterceptor nơi phương thức của Interceptor sẽ được gọi tự động khi đối tượng Employee được tạo ra và cập nhật. Bạn có thể thực hiện nhiều phương thức hơn theo yêu cầu của bạn.

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

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

import hibernate.interceptor.entity.Employee;

public class MyInterceptor extends EmptyInterceptor {

	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 POJO

File: Employee.java

package hibernate.interceptor.entity;

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, tạo các bảng trong cơ sở dữ liệu. Sẽ có một bảng tương ứng với mỗi đối tượng mà bạn sẵn sàng cung cấp persistent. Các đối tượng trên cần phải đượ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 file mapping

Bước này tạo ra một file ánh xạ hướng dẫn Hibernate làm thế nào để ánh xạ các lớp hoặc các lớp đã định nghĩa vào các bảng cơ sở dữ liệu.

File: Employee.hbm.xml

<?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="hibernate.interceptor.entity.Employee" table="EMPLOYEE">
      <meta attribute="class-description">
         Lớp này chứa chi tiết về employee
      </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 file cấu hình Hibernate

File: hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<session-factory>
		<property name="hibernate.dialect">
			org.hibernate.dialect.MySQLDialect
		</property>
		<property name="hibernate.connection.driver_class">
			com.mysql.jdbc.Driver
		</property>

		 
		<property name="hibernate.connection.url">
			jdbc:mysql://localhost/testdb
		</property>
		<property name="hibernate.connection.username">
			root
		</property>
		<property name="hibernate.connection.password">
			1234567890
		</property>

		 
		<mapping resource="Employee.hbm.xml" />

	</session-factory>
</hibernate-configuration>

Tạo lớp ứng dụng

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

import java.util.Iterator;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import hibernate.interceptor.entity.Employee;

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

Kết quả run trên Eclipse

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

Download Source Code

Bài tiếp theo: Hibernate many-to-one relationship với MySQL trên Eclipse
Batch processing trong Hibernate
0