아쿠의 개발 일지

[SpringBoot] Entity간의 관계 설정 본문

Programming/Java

[SpringBoot] Entity간의 관계 설정

디아쿠 2024. 6. 23. 21:09
학생
수강(Enrollment, EnrollmentRepository, EnrollmentService, EnrollmentController)
학생 외래키 수업 외래키
수업(Lecture, LectureRepository) lectureName

 

각각의 엔터티가 다음을 가지고 있다고 치자.

다 제외하고

학생 - 수강

수업 - 수강

이렇게 관계를 맺어서 학생과 수업은 M:N 관계로 수강 테이블(중간)을 통해 join 하는 것을 만들고자 한다.

 

일단 ! 학생 - 수강

import & getter & setter은 생략

@Entity
public class Enrollment {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long idx;

    @ManyToOne
    @JoinColumn(name="lecture_idx")
    private Lecture lecture;


    @ManyToOne
    @JoinColumn(name="student_idx")
    // 외래키
    private Student student;

    public Long getIdx() {
        return idx;
    }

 

한 학생이 여러 수강을 들을 수 있다는 점에서 1 : N 으로

@ManyToOne
@JoinColumn(name="student_idx")
private Student student;

 

@ManyToOne 그리고 @JoinColumn 어노테이션을 사용하면 해당 필드가 외래 키를 포함하는 칼럼이 된다는 것을 의미한다. @JoinColumn(name = "student_id") 는 DB 테이블에서 student_id라는 외래키 칼럼을 생성하여 Student 엔터티와의 관계를 나타낸다고 볼 수 있다.

 

@Entity
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long idx;
    private String name;
    private Integer age;

    @ManyToOne
    @JoinColumn(name="team_idx")
    private Team team;


    @OneToMany(mappedBy = "student")
    private List<Enrollment> enrollments = new ArrayList<Enrollment>();

 

mappedBy는 두 필드 사이의 관계의 주인임을 나타내고, 즉 외래키는 Enrollment 테이블에 존재하며,

Enrollment 엔터티의 student 필드에 의해 이 관계가 매핑 된다는 뜻이다.

 

여기서 수강 테이블과 관계를 맺은 OneToMany를 보면 1:N에서 1을 맡고 있다는 뜻이다.

Student 엔터티가 가진 여러 Enrollment 엔터티를 리스트로 보유 한다는 뜻이다.

 

수업 - 수강

위에 수강 클래스가 있으니 수업만 말하도록 하겠다.

수업도 1:N 관계로 Student 클래스와 별 다를 게 없다.

@Entity
public class Lecture {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long idx;

    private String lectureName;


    @OneToMany(mappedBy = "lecture")
    private List<Enrollment> enrollments = new ArrayList<Enrollment>();

수업인 Lecture은 수업 이름을 컬럼으로 가지고 있고,

OneToMany로 Enrollment 엔터티와 연결되고 있음을 볼 수 있다.

위에서 말 했던 것 처럼 

여러 Enrollment 엔터티를 리스트로 보유하고 있다는 뜻이다.

 

학생 - 수업

학생과 수업은 M:N 으로 학생이 여러 수업을 들을 수 있고, 수업은 여러 학생을 보유할 수 있다.

그렇기에 M:N 관계이다. 이를 어떻게 표현해야 하나,,,

 

    @ManyToMany
    @JoinTable( 
        name = "enrollment",
        joinColumns = @JoinColumn(name = "student_id"), 
        inverseJoinColumns = @JoinColumn(name = "lecture_id") 
    )
    private List<Lecture> lectures = new ArrayList<>();

학생 클래스에서 가지고 왔다.

학생이 수업을 들으니까, 주인 관계는 학생이 가지고 있다.

주인이 되는 쪽에 중간 테이블을 정의한다고 생각하면 된다.

중간 테이블의 이름은 Enrollment 수강 테이블이고, 그 엔터티와 연결되는 외래키를 적어준다.

그리고 Enrollment이 2개의 외래키를 가지고 있다고 했다. 둘이 또 연결되는 외래키를 적어주는 것이다.

그럼 Enrollment 테이블을 통해서 학생과 수업은 연결 될 수 있다.

마지막은 학생이 수강하는 강의 목록을 저장하는 필드임을 나타내는 것이다. (이건 위에서도 많이 나왔다.)

 

    @ManyToMany(mappedBy = "lectures") // Student 엔티티의 lectures 필드에 의해 매핑된다는 것을 나타냅니다.
    private List<Student> students = new ArrayList<>(); // 이 강의를 수강하는 학생 목록을 저장하는 필드입니다.

 

이제 수업 클래스에는 이걸 추가하면 된다.

mappedBy = "" 에는 student 엔터티의 Lectures 필드에 의해 매핑 된다는 것을 알려주는 것이고

관계의 주인이 아닌 측이 사용하는 것이다.

 

Lecture 엔터티는 mappedBy 속성을 통해 Student엔터티의 lectures필드에 의해 매핑 된다는 것을 나타낸다.

 

이 강의를 수강하는 학생 목록을 저장하는 것이다. 다대다 관계이기 때문에 서로 가지고 있는 것 같다.

 

>> 학생 테이블에서 lectures로 수강하는 강의 목록을 저장하는 것을 정의 했으니까,

Lecture  테이블에서 학생 테이블에 있는 lectures 를 통해 매핑 한다는 것이다. 종속되는 쪽이 가지고 있는 게 맞다.

 

대충 끄적인 것

 

728x90

'Programming > Java' 카테고리의 다른 글

[JPA] N+1 문제 해결  (1) 2024.07.10
[Java] 캡슐화 (Encapsulation)  (1) 2024.07.06
[SpringBoot] RestController  (0) 2024.06.23
[Method] method overloading 기본(2)  (0) 2024.06.22
[Method] method Overloading 기본  (0) 2024.06.22