更新時間:2022-05-06 09:40:27 來源:動力節點 瀏覽909次
在這個快速教程中,我們將快速了解如何使用@ManyToMany注釋在 Hibernate 中指定這種類型的關系。
讓我們從一個簡單的實體關系圖開始——它顯示了兩個實體員工和項目之間的多對多關聯:
在這種情況下,任何給定的員工都可以分配到多個項目,并且一個項目可能有多個員工為其工作,從而導致兩者之間的多對多關聯。
我們有一個以employee_id作為主鍵的員工表和一個以project_id作為主鍵的項目表。這里需要一個連接表employee_project來連接雙方。
假設我們已經創建了一個名為spring_hibernate_many_to_many 的數據庫。
我們還需要創建employee和project表以及employee_project連接表,其中employee_id和project_id作為外鍵:
CREATE TABLE `employee` (
`employee_id` int(11) NOT NULL AUTO_INCREMENT,
`first_name` varchar(50) DEFAULT NULL,
`last_name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`employee_id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;
CREATE TABLE `project` (
`project_id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(50) DEFAULT NULL,
PRIMARY KEY (`project_id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;
CREATE TABLE `employee_project` (
`employee_id` int(11) NOT NULL,
`project_id` int(11) NOT NULL,
PRIMARY KEY (`employee_id`,`project_id`),
KEY `project_id` (`project_id`),
CONSTRAINT `employee_project_ibfk_1`
FOREIGN KEY (`employee_id`) REFERENCES `employee` (`employee_id`),
CONSTRAINT `employee_project_ibfk_2`
FOREIGN KEY (`project_id`) REFERENCES `project` (`project_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
設置好數據庫后,下一步將是準備 Maven 依賴項和 Hibernate 配置。
需要使用 JPA 注釋創建模型類Employee和Project :
@Entity
@Table(name = "Employee")
public class Employee {
// ...
@ManyToMany(cascade = { CascadeType.ALL })
@JoinTable(
name = "Employee_Project",
joinColumns = { @JoinColumn(name = "employee_id") },
inverseJoinColumns = { @JoinColumn(name = "project_id") }
)
Set<Project> projects = new HashSet<>();
// standard constructor/getters/setters
}
@Entity
@Table(name = "Project")
public class Project {
// ...
@ManyToMany(mappedBy = "projects")
private Set<Employee> employees = new HashSet<>();
// standard constructors/getters/setters
}
正如我們所見,Employee類和Project類都是相互引用的,這意味著它們之間的關聯是雙向的。
為了映射多對多關聯,我們使用@ManyToMany、@JoinTable和@JoinColumn注釋。讓我們仔細看看它們。
@ManyToMany注解在兩個類中都用于創建實體之間的多對多關系。
這種關聯有兩個方面,即擁有方和反方。在我們的示例中,擁有方是Employee ,因此通過使用Employee類中的@JoinTable注釋在擁有方指定連接表。@JoinTable用于定義連接/鏈接表。在這種情況下,它是Employee_Project。
@JoinColumn注釋用于指定與主表的連接/鏈接列。這里,連接列是employee_id,project_id是反向連接列,因為Project位于關系的反面。
在Project類中,在@ManyToMany注解中使用了mappedBy屬性,表示employees集合被owner側的project集合映射。
為了查看多對多注解的作用,我們可以編寫以下 JUnit 測試:
public class HibernateManyToManyAnnotationMainIntegrationTest {
private static SessionFactory sessionFactory;
private Session session;
//...
@Test
public void givenSession_whenRead_thenReturnsMtoMdata() {
prepareData();
@SuppressWarnings("unchecked")
List<Employee> employeeList = session.createQuery("FROM Employee").list();
@SuppressWarnings("unchecked")
List<Project> projectList = session.createQuery("FROM Project").list();
assertNotNull(employeeList);
assertNotNull(projectList);
assertEquals(2, employeeList.size());
assertEquals(2, projectList.size());
for(Employee employee : employeeList) {
assertNotNull(employee.getProjects());
assertEquals(2, employee.getProjects().size());
}
for(Project project : projectList) {
assertNotNull(project.getEmployees());
assertEquals(2, project.getEmployees().size());
}
}
private void prepareData() {
String[] employeeData = { "Peter Oven", "Allan Norman" };
String[] projectData = { "IT Project", "Networking Project" };
Set<Project> projects = new HashSet<Project>();
for (String proj : projectData) {
projects.add(new Project(proj));
}
for (String emp : employeeData) {
Employee employee = new Employee(emp.split(" ")[0], emp.split(" ")[1]);
employee.setProjects(projects);
for (Project proj : projects) {
proj.getEmployees().add(employee);
}
session.persist(employee);
}
}
//...
}
我們可以看到在數據庫中創建的兩個實體之間的多對多關系:employee、project和employee_project表以及表示該關系的示例數據。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習