Hibernate Учебник по аннотации "многие ко многим"

Hibernate Учебник по аннотации "многие ко многим"

1. Вступление

В этом кратком руководстве мы быстро рассмотрим, как можно использовать аннотацию@ManyToMany для указания этого типа отношений в Hibernate.

2. Типичный пример

Давайте начнем с простой диаграммы отношений сущностей, которая показывает связь "многие ко многим" между двумя объектамиemployee иproject:.

image

В этом сценарии любой заданныйemployee может быть назначен нескольким проектам, а дляproject может быть задействовано несколько сотрудников, что приводит к ассоциации «многие ко многим» между ними.

У нас есть таблицаemployee сemployee_id в качестве первичного ключа и таблицаproject с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. Для получения информации об этом, пожалуйста, обратитесь к статье оGuide to Hibernate4 with 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") }
    )
    Set projects = new HashSet<>();

    // standard constructor/getters/setters
}
@Entity
@Table(name = "Project")
public class Project {
    // ...

    @ManyToMany(mappedBy = "projects")
    private Set employees = new HashSet<>();

    // standard constructors/getters/setters
}

Как видим,both the Employee class and Project classes refer to one another, which means that the association between them is bidirectional.

Чтобы отобразить ассоциацию «многие ко многим», мы используем аннотации@ManyToMany,@JoinTable и@JoinColumn. Давайте посмотрим на них поближе.

Аннотация@ManyToMany используется в обоих классах для создания отношения «многие ко многим» между сущностями.

This association has two sides i.e. the owning side and the inverse side. В нашем примере сторона-владелецEmployee, поэтому таблица соединений указывается на стороне-владельце с помощью аннотации@JoinTable в классеEmployee. @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" };
        Set projects = 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.

Исходный код этого руководства можно найтиover on GitHub.