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, *
运行错误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, *
参考资料