Hibernate-인터셉터

Hibernate에서 배운 것처럼 객체가 생성되고 지속됩니다. 개체가 변경되면 데이터베이스에 다시 저장해야합니다. 이 프로세스는 다음에 개체가 필요할 때까지 계속되며 영구 저장소에서로드됩니다.

따라서 개체는 수명주기의 여러 단계를 거쳐 Interceptor Interface몇 가지 필수 작업을 수행하기 위해 여러 단계에서 호출 할 수있는 메서드를 제공합니다. 이러한 메서드는 세션에서 애플리케이션으로의 콜백으로, 애플리케이션이 저장, 업데이트, 삭제 또는로드되기 전에 영구 개체의 속성을 검사 및 / 또는 조작 할 수 있도록합니다. 다음은 인터셉터 인터페이스 내에서 사용 가능한 모든 방법의 목록입니다.

Sr. 아니. 방법 및 설명
1

findDirty()

이 메서드는 flush() 메서드는 Session 개체에서 호출됩니다.

2

instantiate()

이 메서드는 지속 형 클래스가 인스턴스화 될 때 호출됩니다.

isUnsaved()

이 메서드는 개체가 saveOrUpdate() 방법/

4

onDelete()

이 메서드는 개체가 삭제되기 전에 호출됩니다.

5

onFlushDirty()

이 메소드는 Hibernate가 플러시, 즉 업데이트 작업 중에 객체가 더티 (즉, 변경됨)임을 감지 할 때 호출됩니다.

6

onLoad()

이 메서드는 개체가 초기화되기 전에 호출됩니다.

7

onSave()

이 메서드는 개체가 저장되기 전에 호출됩니다.

8

postFlush()

이 메서드는 플러시가 발생하고 메모리에서 개체가 업데이트 된 후에 호출됩니다.

9

preFlush()

이 메서드는 플러시 전에 호출됩니다.

Hibernate Interceptor는 객체가 응용 프로그램과 데이터베이스 모두에 어떻게 보이는지에 대한 완전한 제어를 제공합니다.

인터셉터를 사용하는 방법?

인터셉터를 구축하려면 다음 중 하나를 구현할 수 있습니다. Interceptor 클래스 직접 또는 확장 EmptyInterceptor수업. 다음은 Hibernate Interceptor 기능을 사용하는 간단한 단계입니다.

인터셉터 생성

Interceptor의 메서드가 다음과 같은 경우 자동으로 호출되는 예제에서 EmptyInterceptor를 확장합니다. Employee개체가 생성되고 업데이트됩니다. 요구 사항에 따라 더 많은 방법을 구현할 수 있습니다.

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

POJO 클래스 생성

이제 EMPLOYEE 테이블과 Employee 클래스를 사용한 첫 번째 예제를 약간 수정 해 보겠습니다.

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

데이터베이스 테이블 생성

두 번째 단계는 데이터베이스에 테이블을 만드는 것입니다. 각 개체에 해당하는 하나의 테이블이 있으며 지속성을 제공 할 의향이 있습니다. 위에서 설명한 객체를 고려하고 다음 RDBMS 테이블에 저장하고 검색해야합니다.

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

매핑 구성 파일 만들기

이 단계는 Hibernate에 지시하는 매핑 파일을 만드는 것입니다. 정의 된 클래스를 데이터베이스 테이블에 매핑하는 방법입니다.

<?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>

애플리케이션 클래스 생성

마지막으로 응용 프로그램을 실행하기 위해 main () 메서드를 사용하여 응용 프로그램 클래스를 만듭니다. 여기서 세션 객체를 생성하는 동안 Interceptor 클래스를 인수로 사용했습니다.

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

컴파일 및 실행

위에서 언급 한 애플리케이션을 컴파일하고 실행하는 단계는 다음과 같습니다. 컴파일 및 실행을 계속하기 전에 PATH 및 CLASSPATH를 적절하게 설정했는지 확인하십시오.

  • 설정 장에서 설명한대로 hibernate.cfg.xml 설정 파일을 생성합니다.

  • 위와 같이 Employee.hbm.xml 매핑 파일을 생성합니다.

  • 위와 같이 Employee.java 소스 파일을 생성하고 컴파일합니다.

  • 위와 같이 MyInterceptor.java 소스 파일을 생성하고 컴파일합니다.

  • 위와 같이 ManageEmployee.java 소스 파일을 생성하고 컴파일합니다.

  • ManageEmployee 바이너리를 실행하여 프로그램을 실행하십시오.

다음과 같은 결과가 나오고 EMPLOYEE 테이블에 레코드가 생성됩니다.

$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

EMPLOYEE 테이블을 확인하면 다음과 같은 레코드가 있어야합니다.

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>