对象关系映射(Object-Relational Mapping,简称 ORM)是将面向对象模型中的对象映射到关系型数据库中的技术。Hibernate 是一个流行的 ORM 框架,它提供了强大的功能来简化这一过程。下面我将详细介绍 Hibernate 中的对象关系映射。
1. 基础概念
在 Hibernate 中,对象关系映射涉及到以下几个概念:
- 实体类:Java 类,代表数据库中的表。
- 属性:Java 类中的字段,映射到数据库表中的列。
- 主键:唯一标识实体类中的每个实例。
- 关系:实体类之间的关联,例如一对一、一对多、多对一和多对多。
2. 基本映射
在 Hibernate 中,你可以使用 JPA 注解或 XML 映射文件来定义实体类与数据库表之间的映射关系。下面是一个使用 JPA 注解的基础映射示例:
import jakarta.persistence.*;
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String email;
// Getters and Setters
}
在这个示例中,Employee
类映射到名为 employees
的数据库表。id
字段是主键,使用 @GeneratedValue
注解设置为主键自动生成策略。
3. 一对一映射
一对一映射通常使用 @OneToOne
注解来实现。以下是一个简单的示例:
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String email;
@OneToOne(mappedBy = "employee")
private Address address;
// Getters and Setters
}
@Entity
@Table(name = "addresses")
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String street;
private String city;
@OneToOne
@JoinColumn(name = "emp_id")
private Employee employee;
// Getters and Setters
}
在这个例子中,Employee
类有一个 address
属性,它表示一个一对一的关系。Address
类有一个 employee
属性,它也表示一个一对一的关系。mappedBy
属性告诉 Hibernate 从哪个方向获取关系信息。
4. 一对多映射
一对多映射使用 @OneToMany
和 @ManyToOne
注解来实现。以下是一个简单的示例:
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String email;
@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Project> projects;
// Getters and Setters
}
@Entity
@Table(name = "projects")
public class Project {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String projectName;
@ManyToOne
@JoinColumn(name = "emp_id")
private Employee employee;
// Getters and Setters
}
在这个例子中,Employee
类有一个 projects
属性,它表示一个员工可以有多个项目。Project
类有一个 employee
属性,它表示一个项目属于一个员工。
5. 多对一映射
多对一映射与一对多映射类似,只是方向相反。下面是一个简单的示例:
@Entity
@Table(name = "projects")
public class Project {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String projectName;
@ManyToOne
@JoinColumn(name = "emp_id")
private Employee employee;
// Getters and Setters
}
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String email;
@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Project> projects;
// Getters and Setters
}
在这个例子中,Project
类有一个 employee
属性,它表示一个项目属于一个员工。Employee
类有一个 projects
属性,它表示一个员工可以有多个项目。
6. 多对多映射
多对多映射通常需要一个额外的关联表。以下是一个简单的示例:
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String email;
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(
name = "employee_project",
joinColumns = @JoinColumn(name = "emp_id"),
inverseJoinColumns = @JoinColumn(name = "proj_id")
)
private List<Project> projects;
// Getters and Setters
}
@Entity
@Table(name = "projects")
public class Project {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String projectName;
@ManyToMany(mappedBy = "projects")
private List<Employee> employees;
// Getters and Setters
}
在这个例子中,Employee
类有一个 projects
属性,它表示一个员工可以参与多个项目。Project
类有一个 employees
属性,它表示一个项目可以由多个员工参与。
7. 继承映射
Hibernate 还支持继承映射,这使得你可以将具有共同属性的实体类组织在一起。这里有几种不同的继承策略:
- 单表策略(Single Table):所有子类共享同一张表。
- 每类一张表策略(Table per Class):每个子类都有一张独立的表。
- 每表一子类策略(Table per Subclass):基类有一张表,每个子类都有自己的表。
下面是一个简单的单表策略示例:
@Entity
@Table(name = "employees")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type")
public abstract class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String email;
// Getters and Setters
}
@Entity
@DiscriminatorValue("manager")
public class Manager extends Employee {
private double bonus;
// Getters and Setters
}
@Entity
@DiscriminatorValue("worker")
public class Worker extends Employee {
private double hourlyRate;
// Getters and Setters
}
在这个例子中,Employee
类是抽象的,并且定义了一个名为 type
的区分器列。Manager
和 Worker
类继承了 Employee
类,并且每个子类都有一个区分器值。
8. 组件映射
组件映射用于将一个 Java 类映射到一个复合列。例如,你可以将一个地址类映射到数据库中的一个地址列。
public class Address {
private String street;
private String city;
private String zipCode;
// Getters and Setters
}
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String email;
@Embedded
private Address address;
// Getters and Setters
}
在这个例子中,Address
类是一个组件类,它被嵌入到 Employee
类中。
9. 枚举映射
枚举类型也可以被映射到数据库中。下面是一个简单的示例:
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String email;
@Enumerated(EnumType.STRING)
private Gender gender;
// Getters and Setters
}
public enum Gender {
MALE, FEMALE, OTHER
}
在这个例子中,Gender
枚举被映射到数据库中的一列。
总结
这些示例展示了 Hibernate 中一些基本的对象关系映射技术。根据你的具体需求,你可以选择合适的映射类型来处理实体之间的关系。如果你需要更详细的信息或特定的示例,请随时告诉我。