Hibernate注解
到目前為止,已經看到Hibernate如何使用XML映射文件從POJO的數據到數據庫表的改造,反之亦然。 Hibernate注解是一個冇有使用XML文件來定義映射的最新方法。可以在除或替換的XML映射元數據使用注解。
Hibernate的注解是強大的方式來提供元數據對象和關係表的映射。所有的元數據被杵到一起的代碼POJO java文件這可以幫助用戶在開發過程中同時要了解表的結構和POJO。
如果打算讓應用程序移植到其他EJB3規範的ORM應用程序,必須使用注解來表示映射信息,但仍然如果想要更大的靈活性,那麼應該使用基於XML的映射去。
環境設置Hibernate注釋
首先,必須確保使用的是JDK5.0,否則,需要JDK升級到JDK5.0帶注解的原生支持的優勢。
其次,需要安裝Hibernate的3.x注解分發包,可從SourceForge上: (Download Hibernate Annotation) 並拷貝 hibernate-annotations.jar, lib/hibernate-comons-annotations.jar 和 lib/ejb3-persistence.jar 從Hibernate注解分配到CLASSPATH
注釋的類實例:
正如提到的,同時使用Hibernate注釋工作的所有元數據杵成隨著代碼的POJO java文件上麵這可以幫助用戶在開發過程中同時了解表結構和POJO。
考慮到將要使用下麵的EMPLOYEE表來存儲的對象:
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) );
下麵是用注解來映射與定義的EMPLOYEE表的對象Employee類的映射:
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檢測@Id注釋是對一個字段,並假設它應該直接通過在運行時域訪問一個對象的屬性。如果將@Id注釋getId()方法,將通過getter和setter方法默認情況下允許訪問屬性。因此,所有其他注釋也被放置在任一字段或getter方法,以下所選擇的策略。下麵的部分將解釋在上麵的類中使用的注釋。
@Entity 注解:
在EJB3規範說明都包含在javax.persistence包,所以我們導入這個包作為第一步。其次,我們使用了@Entity注解來這標誌著這個類作為一個實體bean Employee類,因此它必須有一個無參數的構造函數,總算是有保護的範圍可見。
@Table 注解:
@Table注釋允許指定的表將被用於保存該實體在數據庫中的詳細信息。
@Table注釋提供了四個屬性,允許覆蓋表的名稱,它的目錄,它的架構,並執行對列的唯一約束在表中。現在,我們使用的是剛剛是EMPLOYEE表的名稱。
@Id 和 @GeneratedValue 注解:
每個實體bean將有一個主鍵,注釋在類的@Id注解。主鍵可以是單個字段或根據表結構的多個字段的組合。
默認情況下,@Id注解會自動確定要使用的最合適的主鍵生成策略,但可以通過應用@GeneratedValue注釋,它接受兩個參數,strategy和generator,不打算在這裡討論,隻使用默認的默認鍵生成策略。讓Hibernate確定要使用的generator類型使不同數據庫之間代碼的可移植性。
@Column 注解:
@Column批注用於指定的列到一個字段或屬性將被映射的細節。可以使用列注釋以下最常用的屬性:
-
name屬性允許將顯式指定列的名稱。
-
length 屬性允許用於映射一個value尤其是對一個字符串值的列的大小。
-
nullable 屬性允許該列被標記為NOT NULL生成架構時。
-
unique 屬性允許被標記為隻包含唯一值的列。
創建應用程序類:
最後,我們將創建應用程序類的main()方法來運行應用程序。我們將使用這個應用程序,以節省一些員工的記錄,然後我們將申請CRUD操作上的記錄。
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(); } } }
數據庫配置:
現在,讓我們創建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> <!-- 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>
編譯和執行:
下麵是步驟來編譯並運行上述應用程序。請確保已在進行的編譯和執行之前,適當地設置PATH和CLASSPATH。
-
從路徑中刪除Employee.hbm.xml映射文件。
-
創建Employee.java源文件,如上圖所示,並編譯它。
-
創建ManageEmployee.java源文件,如上圖所示,並編譯它。
-
執行ManageEmployee二進製文件來運行程序。
會得到以下結果,並記錄將在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
如果檢查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>