Framework/SpringBoot

[SpringBoot] @OneToMany, @ManyToOne, @ManyToMany 연관 관계 매핑, @JoinTable

  • -

@OneToMany

@OneToMany 어노테이션은 하나의 엔티티와 다른 엔티티간의 일대다 관계를 매핑하는데 사용됩니다.

일대다 관계에서는 하나의 인스턴스가 다른 엔티티의 여러 인스턴스와 연결됩니다.

@Entity
public class Department {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
    private List<Employee> employees = new ArrayList<>();
}

@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}

회사의 부서(Department)와 직원(Employee)의 관계를 예시로 들자면 

부서는 여러 직원을 포함하지만 직원은 하나의 부서에 속합니다.\

 

따라 부서에서 직원과 매핑할 필드에 OneToMany 어노테이션을 사용해 일대다 관계를 형성할 수 있습니다.

(일이 부서, 다가 직원)

casecade = CascadeType.ALL

위 예제에서 사용된

cascade = CasecaseTypeAll 에 대한 포스팅입니다.

 

*작성 후 추가 예정

@ManyToOne

@ManyToOne 어노테이션은 두 개의 엔티티 간에 다대일 관계를 정의하는데에 사용됩니다.

다대일 관계에서는 하나의 엔티티 인스턴스가 다른 엔티티의 여러 인스턴스와 연결될 수 있습니다. 

 

책(Book)과 작가(Author)를 예시로 들어보겠습니다. 

단, 한 책에 하나의 저자만 있다고 가정하겠습니다.

@Entity
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;
    
    @ManyToOne
    @JoinColumn(name = "author_id")
    private Author author;
}

@Entity
public class Author {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}

위에서 @ManyToOne 어노테이션이 붙은 칼럼은 책의 저자입니다.

 

하나의 책은 저자 하나만을 포함하지만, 하나의 저자는 여러 개의 책을 출간할 수 있습니다.

이와 같은 관계에서 @ManyToOne 어노테이션을 의 역할을 하는 엔티티의 

저자를 join할 필드에 붙여주면 됩니다. 

 

@OneToMany &  @ManyToOne

앞서 보여드린 두 개의 예제에서 Employee와 Author에 ManyToOne과 OneToMany 어노테이션을 붙여보겠습니다.

@Entity
public class Department {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
    private List<Employee> employees = new ArrayList<>();

}

@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @ManyToOne
    @JoinColumn(name = "department_id")
    private Department department;

}
@Entity
public class Author {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    
    @OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
    private List<Book> books = new ArrayList<>();

}

@Entity
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;
    
    @ManyToOne
    @JoinColumn(name = "author_id")
    private Author author;

}

이처럼 연관 관계가 있는 각각의 엔티티에 ManyToOne과 OneToMany를 사용할 수 있습니다.

 

 

@ManyToMany

@ManyToMay 어노테이션은 다대다 관계에서 사용됩니다.

한 학생은 여러 개의 과목을 수강할 수 있고, 하나의 과목도 여러 학생을 포함할 수 있습니다.

이러한 관계에서 @ManyToMany 어노테이션을 사용합니다. 

@Entity
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    
    @ManyToMany
    @JoinTable(
        name = "student_course",
        joinColumns = @JoinColumn(name = "student_id"),
        inverseJoinColumns = @JoinColumn(name = "course_id")
    )
    private Set<Course> courses = new HashSet<>();

}

@Entity
public class Course {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;
    
    @ManyToMany(mappedBy = "courses")
    private Set<Student> students = new HashSet<>();

}

@JoinTable

@JoinTable 어노테이션은 테이블을 이용하여 연관 관계를 매핑할 때 사용됩니다.

 

일대다, 다대일 관계에서는 주로 조인 칼럼을 이용했는데. 

조인 테이블을 이용하여 연관 관계를 관리할 때 사용되는 어노테이션입니다.

 

조인 테이블이라는 별도의 테이블을 사용해서 연관 관계를 정리할 때, 

조인 테이블은 연관 관계가 있는 두 개의 테이블의 외래 키를 필드로 가지고 있습니다. 

 

JoinTable의 속성을 살펴보겠습니다.

  • name: 조인 테이블의 이름
  • joinColumns = @JoinColumn(name = "student_id"): student_id라는 이름의 Student의 외래키를 가지고 있는 칼럼 추가
  • inverseJoinColumns = @JoinColumn(name = "course_id"): course_id라는 이름의 Course의 외래키를 가지고 있는 칼럼 추가 

위처럼 생성된 조인 테이블을 sql로 보여드리자면 다음과 같습니다.

CREATE TABLE student_course (
    student_id BIGINT,
    course_id BIGINT
);

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.