[Hibernate] 注解映射例子
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