Hibernate - Chú thích

Cho đến nay, bạn đã thấy cách Hibernate sử dụng tệp ánh xạ XML để chuyển đổi dữ liệu từ POJO sang các bảng cơ sở dữ liệu và ngược lại. Chú thích ngủ đông là cách mới nhất để xác định ánh xạ mà không cần sử dụng tệp XML. Bạn có thể sử dụng chú thích để bổ sung hoặc thay thế cho siêu dữ liệu ánh xạ XML.

Hibernate Annotations là cách mạnh mẽ để cung cấp siêu dữ liệu cho ánh xạ đối tượng và bảng quan hệ. Tất cả siêu dữ liệu được gộp vào tệp java POJO cùng với mã, điều này giúp người dùng hiểu cấu trúc bảng và POJO đồng thời trong quá trình phát triển.

Nếu bạn định làm cho ứng dụng của mình có thể di động tới các ứng dụng ORM tuân thủ EJB 3 khác, bạn phải sử dụng chú thích để đại diện cho thông tin ánh xạ, nhưng nếu bạn muốn linh hoạt hơn, thì bạn nên sử dụng ánh xạ dựa trên XML.

Thiết lập môi trường cho chú thích ngủ đông

Trước hết, bạn phải đảm bảo rằng bạn đang sử dụng JDK 5.0, nếu không, bạn cần nâng cấp JDK của mình lên JDK 5.0 để tận dụng sự hỗ trợ gốc cho các chú thích.

Thứ hai, bạn sẽ cần cài đặt gói phân phối chú thích Hibernate 3.x, có sẵn từ sourceforge: ( Tải xuống Hibernate Annotation ) và sao chéphibernate-annotations.jar, lib/hibernate-comons-annotations.jarlib/ejb3-persistence.jar từ bản phân phối Chú thích ngủ đông đến CLASSPATH của bạn.

Ví dụ về lớp được chú thích

Như tôi đã đề cập ở trên khi làm việc với Hibernate Annotation, tất cả siêu dữ liệu được gộp chung vào tệp POJO java cùng với mã, điều này giúp người dùng hiểu cấu trúc bảng và POJO đồng thời trong quá trình phát triển.

Hãy xem xét chúng ta sẽ sử dụng bảng EMPLOYEE sau đây để lưu trữ các đối tượng của chúng ta -

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

Sau đây là ánh xạ của lớp Nhân viên với các chú thích để ánh xạ các đối tượng với bảng EMPLOYEE được xác định -

import javax.persistence.*;

@Entity
@Table(name = "EMPLOYEE")
public class Employee {
   @Id @GeneratedValue
   @Column(name = "id")
   private int id;

   @Column(name = "first_name")
   private String firstName;

   @Column(name = "last_name")
   private String lastName;

   @Column(name = "salary")
   private int salary;  

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

Hibernate phát hiện rằng chú thích @Id nằm trên một trường và giả định rằng nó sẽ truy cập trực tiếp các thuộc tính của một đối tượng thông qua các trường trong thời gian chạy. Nếu bạn đặt chú thích @Id trên phương thức getId (), bạn sẽ cho phép truy cập vào các thuộc tính thông qua các phương thức getter và setter theo mặc định. Do đó, tất cả các chú thích khác cũng được đặt trên các trường hoặc các phương thức getter, theo chiến lược đã chọn.

Phần sau sẽ giải thích các chú thích được sử dụng trong lớp trên.

Chú thích @Entity

Các chú thích chuẩn EJB 3 được chứa trong javax.persistence, vì vậy chúng tôi nhập gói này như bước đầu tiên. Thứ hai, chúng tôi sử dụng@Entity chú thích cho lớp Employee, đánh dấu lớp này là một bean thực thể, vì vậy nó phải có một phương thức khởi tạo không đối số có thể nhìn thấy với phạm vi ít nhất được bảo vệ.

@Table Annotation

Chú thích @Table cho phép bạn chỉ định các chi tiết của bảng sẽ được sử dụng để duy trì thực thể trong cơ sở dữ liệu.

Chú thích @Table cung cấp bốn thuộc tính, cho phép bạn ghi đè tên của bảng, danh mục và lược đồ của nó, đồng thời thực thi các ràng buộc duy nhất trên các cột trong bảng. Hiện tại, chúng tôi chỉ sử dụng tên bảng, là NHÂN VIÊN.

Chú thích @Id và @GeneratedValue

Mỗi hạt thực thể sẽ có một khóa chính, mà bạn chú thích trên lớp có @Idchú thích. Khóa chính có thể là một trường đơn lẻ hoặc kết hợp nhiều trường tùy thuộc vào cấu trúc bảng của bạn.

Theo mặc định, chú thích @Id sẽ tự động xác định chiến lược tạo khóa chính thích hợp nhất sẽ được sử dụng nhưng bạn có thể ghi đè điều này bằng cách áp dụng @GeneratedValue chú thích, có hai tham số strategygeneratormà tôi sẽ không thảo luận ở đây, vì vậy chúng ta hãy chỉ sử dụng chiến lược tạo khóa mặc định. Cho phép Hibernate xác định loại trình tạo sẽ sử dụng giúp mã của bạn có thể di động giữa các cơ sở dữ liệu khác nhau.

Chú thích @Column

Chú thích @Column được sử dụng để chỉ định chi tiết của cột mà một trường hoặc thuộc tính sẽ được ánh xạ tới. Bạn có thể sử dụng chú thích cột với các thuộc tính được sử dụng phổ biến nhất sau đây:

  • name thuộc tính cho phép tên của cột được chỉ định rõ ràng.

  • length thuộc tính cho phép kích thước của cột được sử dụng để ánh xạ một giá trị đặc biệt cho một giá trị Chuỗi.

  • nullable thuộc tính cho phép cột được đánh dấu KHÔNG ĐỦ khi lược đồ được tạo.

  • unique thuộc tính cho phép cột được đánh dấu là chỉ chứa các giá trị duy nhất.

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. Chúng tôi sẽ sử dụng ứng dụng này để lưu một số hồ sơ của Nhân viên và sau đó chúng tôi sẽ áp dụng các hoạt động CRUD trên các hồ 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.cfg.AnnotationConfiguration;
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 AnnotationConfiguration().
                   configure().
                   //addPackage("com.xyz") //add package if used.
                   addAnnotatedClass(Employee.class).
                   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();
      Transaction tx = null;
      Integer employeeID = null;
      
      try {
         tx = session.beginTransaction();
         Employee employee = new Employee();
         employee.setFirstName(fname);
         employee.setLastName(lname);
         employee.setSalary(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();
      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();
      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();
      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(); 
      }
   }
}

Cấu hình cơ sở dữ liệu

Bây giờ hãy để chúng tôi tạo hibernate.cfg.xml tập tin cấu hình để xác định các tham số liên quan đến cơ sở dữ liệu.

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

      <!-- Assume students is the database name -->
   
      <property name = "hibernate.connection.url">
         jdbc:mysql://localhost/test
      </property>
   
      <property name = "hibernate.connection.username">
         root
      </property>
   
      <property name = "hibernate.connection.password">
         cohondob
      </property>

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

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.

  • Xóa tệp ánh xạ Employee.hbm.xml khỏi đường dẫ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 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 EMPLOYEE.

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

First Name: Zara  Last Name: Ali  Salary: 1000
First Name: Daisy  Last Name: Das  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000
First Name: Zara  Last Name: Ali  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000

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>