Hibernate 注解(Hibernate Annotation) 是一種比較新的方式,通過在 java 簡單類增加注解,來聲明 java 類和數據庫表的映射,作用和 xml 文件相似。hibernate 注解可以用來增強,或者替換 xml 的映射聲明方式。
hibernate 注解功能需要使用下面三個 jar 文件
hibernate-annotations.jar
ejb3-persistence.jar
hibernate-commons-annotations.jar
代碼的目錄結構如下:

hibernate.cfg.xml 存儲數據庫信息,如數據庫類型,賬號密碼,數據庫名稱。
Employee.java Employee 實體類,包含注解,聲明 java 類和數據庫表結構的映射關系。
ManageEmployee.java 管理 Employee,並對外提供操作 Employee 對象數據的接口。
App.java,演示本例子。
代碼詳情
在數據庫中,創建 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) );
創建 java 簡單類,含有注解。
@Entity 表明 Employee 類似一個實體類( Entity Bean ),並且有一個無參構造函數
@Table 聲明用於持久化當前類( Employee ) 的數據庫表名。
@Id,每一個實體類都有一個主鍵,用 @Id 聲明
@Column,表明當前變量所映射的數據庫表的字段
package tony.hibernateAnnotation; import javax.persistence.*; @Entity @Table(name="EMPLOYEE") public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @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; } }
ManageEmployee.java Employee 的操作工具類。對業務層提供操作 Employee 的接口。
package tony.hibernateAnnotation; 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; public class ManageEmployee { private static SessionFactory factory; { factory = new Configuration().configure() .addPackage("tony.hibernateAnnotation") .addAnnotatedClass(Employee.class) .buildSessionFactory(); } public int 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; } public void listEmployees(){ Session session = factory.openSession(); Transaction tx = null; tx = session.beginTransaction(); List<Employee> employees = session.createQuery("FROM Employee").list(); for(Employee emp : employees){ System.out.println(emp.getId() + ", " + emp.getFirstName() + ", " + emp.getLastName() + ", " + emp.getSalary());; } tx.commit(); session.close(); } public List<Employee> getAllEmployees(){ Session session = factory.openSession(); Transaction tx = null; tx = session.beginTransaction(); List<Employee> employees = session.createQuery("FROM Employee").list(); tx.commit(); session.close(); return employees; } public void updateEmployee(int employeeId, int salary){ Session session = factory.openSession(); Transaction tx = null; tx = session.beginTransaction(); Employee emp = session.get(Employee.class, employeeId); emp.setSalary(salary); session.update(emp); tx.commit(); session.close(); } public void deleteEmployee(int employeeId){ Session session = factory.openSession(); Transaction tx = null; tx = session.beginTransaction(); Employee emp = session.get(Employee.class, employeeId); session.delete(emp); tx.commit(); session.close(); } }
pom.xml 本例子所依賴的包
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.2.3.Final</version> </dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-annotations --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-annotations</artifactId> <version>3.5.6-Final</version> </dependency> <!-- https://mvnrepository.com/artifact/org.hibernate/ejb3-persistence --> <dependency> <groupId>org.hibernate</groupId> <artifactId>ejb3-persistence</artifactId> <version>3.3.2.Beta1</version> </dependency> <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-commons-annotations --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-commons-annotations</artifactId> <version>3.2.0.Final</version> </dependency>
說明
根據 tutorialspoint 例子的代碼,無法運行成功,可能與 hibernate 使用版本有關,修正下面錯誤后,運作正常。
運行錯誤 1
java.lang.NoClassDefFoundError: org/hibernate/cfg/Mappings
在ManageEmployee.java 中,創建 SessionFactory 對象時,應該使用 org.hibernate.cfg.Configuration,而不是用 org.hibernate.cfg.AnnotationConfiguration。參考 java.lang.NoClassDefFoundError, stackOverflow
運行錯誤2
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'hibernatetest.hibernate_sequence' doesn't exist
這應該和 hibernate 版本有關,在 hibernate 5 及以上版本,在 java 文件中定義主鍵字段時,使用 @GeneratedValue(strategy = GenerationType.IDENTITY) 代替 @GeneratedValue。參考 Hibernate-sequence doesn't exist, stackOverflow
參考資料
Hibernate - Annotations, tutorialspoint
