Cho đến nay, bạn đã thấy cách Hibernate sử dụng file mapping XML để chuyển đổi dữ liệu từ Java POJO sang các bảng cơ sở dữ liệu và ngược lại. Hibernate Annotations là cách mới nhất để định nghĩa các mapping mà không cần sử dụng file XML. Bạn có thể sử dụng các annotation bổ sung hoặc để thay thế siêu dữ mapping XML.
Hibernate Annotations là cách mạnh mẽ để cung cấp siêu dữ liệu cho việc mapping đối tượng và bảng quan hệ. Tất cả các siêu dữ liệu được định nghĩa vào file java POJO cùng với mã này giúp người sử dụng đồng thời hiểu được cấu trúc bảng và POJO trong quá trình phát triển.
Nếu bạn muốn ứng dụng của bạn chuyển sang các ứng dụng ORM tương thích khác của EJB 3, bạn phải sử dụng các annotation để biểu diễn các thông tin mapping nhưng vẫn cần sử dụng các mapping dựa trên XML.
Nội dung chính
Thiết lập môi trường cho Hibernate Annotation
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 phải nâng cấp JDK của mình lên JDK 5.0 hoặc bản mới hơn để được hỗ trợ sử dụng annotation.
Thứ hai, bạn sẽ cần phải cài đặt gói Hibernate 3.x annotations, có sẵn từ sourceforge: (Download Hibernate Annotations) và sao chép hibernate-annotations.jar, lib/hibernate-comons-annotations.jar và lib/ejb3-persistence.jar từ file tải về đến CLASSPATH của bạn
Hoặc bạn có thể add các dependency vào file pom.xml như sau:
<dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>3.6.3.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-annotations</artifactId> <version>3.5.6-Final</version> </dependency> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>3.12.1.GA</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> </dependencies>
Tạo lớp Entity với các annotation
Như đã đề cập ở trên trong khi làm việc với Hibernate Annotation tất cả các siêu dữ liệu được định nghĩa vào file java POJO cùng với mã này giúp người sử dụng đồng thời hiểu được cấu trúc bảng và lớp POJO trong quá trình phát triển.
Tạo bảng EMPLOYEE để lưu trữ đối tượng
create table testdb.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à việc mapping lớp Employee với các annotation để ánh xạ các đối tượng với bảng EMPLOYEE được định nghĩa ở trên:
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; } }
Sử dụng chú thích trên tương đương với file mapping xml như sau:
Hibernate nhận ra rằng chú thích @Id nằm trên một trường và giả định rằng các thuộc tính của một đối tượng được truy cập trực tiếp thông qua các trường tại runtime. Nếu bạn đã đặt chú thích @Id vào phương thức getId(), bạn sẽ cho phép truy cập thuộc tính thông qua các phương thức getter và setter của theo mặc định. Do đó, tất cả các chú thích khác cũng được đặt trên cả hai trường hoặc phương thức getter. Dưới đây giải thích các chú thích được sử dụng trong lớp trên.
@Entity Annotation:
Các chú thích tiêu chuẩn EJB 3 được chứa trong gói javax.persistence, vì vậy trước tiên chúng ta phải import gói này. Thứ hai, chúng ta đã sử dụng chú thích Entity vào lớp Employee đánh dấu lớp này như một Entity Bean, do đó nó phải có một constructor không có đối số mà có kiểu là public.
@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 để lưu 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, lược đồ, bắt buộc các ràng buộc duy nhất trên các cột trong bảng. Trong lớp Employee ở trên chúng ta đang sử dụng tên bảng là EMPLOYEE.
@Id and @GeneratedValue Annotations:
Mỗi entity bean sẽ có một khóa chính, mà bạn chú thích trên lớp với chú thích @Id. Khóa chính có thể là một trường duy nhất 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 primary key, nhưng bạn có thể ghi đè bằng cách áp dụng chú thích @GeneratedValue có hai tham số strategy và generator. Chúng ta chỉ sử dụng chiến lược tạo key mặc định. Cho phép Hibernate xác định loại kiểu tạo nào để sử dụng làm cho mã di chuyển giữa các cơ sở dữ liệu khác nhau.
@Column Annotation:
Chú thích @Column được sử dụng để chỉ định chi tiết của cột mà trường hoặc thuộc tính sẽ được ánh xạ. 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:
- Thuộc tính name được sử dụng để chị định tên cột nào trong db map với tên trường được chú thích.
- Thuộc tính length 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ị String.
- Thuộc tính nullable cho phép cột được đánh dấu KHÔNG NULL khi schema được tạo ra.
- Thuộc tính unique cho phép cột được đánh dấu chỉ chứa các giá trị duy nhất.
Tạo file cấu hình Hibernate
Tạo file cấu hình hibernate.cfg.xml để 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> <!-- Thông tin kết nối db --> <property name="hibernate.connection.url"> jdbc:mysql://localhost/testdb </property> <property name="hibernate.connection.username"> root </property> <property name="hibernate.connection.password"> 1234567890 </property> </session-factory> </hibernate-configuration>
Tạo lớp ứng dụng
Cuối cùng, chúng ta sẽ tạo lớp ứng dụng để run bằng phương thức main(). Chúng ta sẽ sử dụng ứng dụng này để lưu các employee và sau đó chúng ta sẽ áp dụng các thao tác CRUD trên các employee đó.
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.AnnotationConfiguration; import vn.kienthuclaptrinh.hibernate.annotation.entity.Employee; 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) { ex.printStackTrace(); 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(); } } }
Kết quả run trên eclipse
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
Download Source Code Eclipse