Автор оригинала: Zeger Hendrikse.
1. введение
В этом кратком руководстве мы кратко рассмотрим, как аннотацию @ManyToMany можно использовать для указания этого типа отношений в режиме гибернации.
2. Типичный Пример
Давайте начнем с простой диаграммы отношений сущностей, которая показывает связь “многие ко многим” между двумя сущностями сотрудник и проект:
В этом сценарии любой данный сотрудник может быть назначен нескольким проектам, и в проекте может работать несколько сотрудников, что приводит к связи между ними “многие ко многим”.
У нас есть employee таблица с employee_id в качестве первичного ключа и project таблица с project_id в качестве первичного ключа. Для соединения обеих сторон здесь требуется объединенная таблица employee_project .
3. Настройка базы данных
Предположим, у нас есть уже созданная база данных с именем spring_hibernate_many_to_many.
Нам также необходимо создать таблицы employee и project вместе с таблицей employee_project join с 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 и конфигурация гибернации. Для получения информации об этом, пожалуйста, обратитесь к статье о руководстве по гибернации 4 с помощью Spring
4. Классы Моделей
Классы моделей Employee и Project должны быть созданы с аннотациями JPA:
@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") } ) Setprojects = new HashSet<>(); // standard constructor/getters/setters }
@Entity @Table(name = "Project") public class Project { // ... @ManyToMany(mappedBy = "projects") private Setemployees = new HashSet<>(); // standard constructors/getters/setters }
Как мы видим, классы Employee и Project ссылаются друг на друга, что означает, что связь между ними является двунаправленной.
Чтобы сопоставить ассоциацию “многие ко многим”, мы используем @ManyToMany , @JoinTable и @JoinColumn аннотации. Давайте рассмотрим их поближе.
Аннотация @ManyToMany используется в обоих классах для создания отношения “многие ко многим” между сущностями.
Эта ассоциация имеет две стороны, то есть сторону владения и обратную сторону. В нашем примере сторона-владелец-это Сотрудник , поэтому таблица соединений указывается на стороне владельца с помощью аннотации @JoinTable в классе Сотрудник . @JoinTable используется для определения таблицы соединений/ссылок. В данном случае это Employee_Project.
Аннотация @JoinColumn используется для указания столбца соединения/связывания с основной таблицей. Здесь столбец соединения является employee_id и project_id является обратным столбцом соединения, так как Project находится на обратной стороне отношения.
В классе Project атрибут mappedBy используется в аннотации @ManyToMany , чтобы указать, что коллекция employees сопоставляется коллекцией projects на стороне владельца.
5. Исполнение
Чтобы увидеть аннотацию “многие ко многим” в действии, мы можем написать следующий тест JUnit:
public class HibernateManyToManyAnnotationMainIntegrationTest { private static SessionFactory sessionFactory; private Session session; // ... @Test public void givenData_whenInsert_thenCreatesMtoMrelationship() { String[] employeeData = { "Peter Oven", "Allan Norman" }; String[] projectData = { "IT Project", "Networking Project" }; Setprojects = new HashSet<>(); for (String proj : projectData) { projects.add(new Project(proj)); } for (String emp : employeeData) { Employee employee = new Employee(emp.split(" ")[0], emp.split(" ")[1]); assertEquals(0, employee.getProjects().size()); employee.setProjects(projects); session.persist(employee); assertNotNull(employee); } } @Test public void givenSession_whenRead_thenReturnsMtoMdata() { @SuppressWarnings("unchecked") List employeeList = session.createQuery("FROM Employee") .list(); assertNotNull(employeeList); for(Employee employee : employeeList) { assertNotNull(employee.getProjects()); } } // ... }
Мы можем видеть связь “многие ко многим” между двумя сущностями, созданными в базе данных: таблицами employee , project и employee_project с образцами данных, представляющими эту связь.
6. Заключение
В этом руководстве мы рассмотрели, как создавать сопоставления с помощью аннотаций Hibernate “многие ко многим”, что является более удобным аналогом по сравнению с созданием файлов сопоставления XML.
Исходный код этого учебника можно найти на GitHub .