专注Java教育14年 全国咨询/投诉热线:444-1124-454
赢咖4LOGO图
始于2009,口口相传的Java黄埔军校
首页 hot资讯 Hibernate多对多注解教程

Hibernate多对多注解教程

更新时间:2022-05-06 09:40:27 来源:赢咖4 浏览586次

1. 简介

在这个快速教程中,我们将快速了解如何使用@ManyToMany注释在 Hibernate 中指定这种类型的关系。

2. 一个典型的例子

让我们从一个简单的实体关系图开始——它显示了两个实体员工和项目之间的多对多关联:

在这种情况下,任何给定的员工都可以分配到多个项目,并且一个项目可能有多个员工为其工作,从而导致两者之间的多对多关联。

我们有一个以employee_id作为主键的员工表和一个以project_id作为主键的项目表。这里需要一个连接表employee_project来连接双方。

3. 数据库设置

假设我们已经创建了一个名为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 配置。

4. 模型类

需要使用 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集合映射。

5. 执行

为了查看多对多注解的作用,我们可以编写以下 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表以及表示该关系的示例数据。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>