스프링/JPA

[JPA] 다대일 연관 관계 매핑

imcoding 2022. 9. 13. 18:27
Entity
다대일 연관 관계 매핑

연관관계의 주인?

연관관계의 주인에 대한 개념이 없다면 아래 글을 먼저 읽고 오시길 권장드립니다.

https://imcoding.tistory.com/56

 

[JPA] 엔티티 연관관계의 주인

연관관계의 주인 개념 외래키를 관리할 객체를 말한다. 엔티티의 연관관계는 테이블에서와 객체에서 각각 존재한다. 테이블에서는 사실 연관관계의 주인이 누구건간에 테이블 구조는 똑같다.

imcoding.tistory.com

 

 

 

다대일(N : 1) 연관 관계 매핑

1. 멤버와 팀이 N : 1 관계로 있다.
2. 멤버는 하나의 팀에만 소속될 수 있고, 한 팀당 여러명의 멤버가 있을 수 있다.

 

이해를 돕기 위해 위 구조를 가지고 설명을 시작하겠다.

 

우선, 외래키는 멤버(N) 테이블에 존재한다. (N : 1 구조에서 항상 N 쪽이 보유)

 

다대일에서 연관 관계의 주인은 멤버(N) 객체로 정한다.

 

 

다대일 단방향 매핑

 

 

@Entity
@Getter
@Setter
public class Member {
    @ManyToOne
    @JoinColumn(name = "team_id")
    private Team team;
}

가장 많이 사용되는 연관관계 매핑이다.

 

Member 객체에서 봤을 때 다대일(N : 1)이기 때문에 @ManyToOne을 붙여준다.

 

그리고 JoinColumn으로 연관관계의 주인임을 정해줄 수 있다.

 

해당 컬럼에는 Team 객체의 Id값이 들어올 것이며, 컬럼 이름은 name으로 정해주었다.

 

다(N)가 되는 Member객체를 주인으로 정해줬기 때문에 "다대일 연관관계 매핑"이라 부르는 것이다.

 

fetch, cascade 등 매핑에 설정값을 더해줄 수도 있지만

기본적으로 이렇게 다대일 단방향 매핑을 끝낼 수 있다.

 

 

다대일 양방향 매핑

단방향 매핑만큼 양방향도 간단하다.

 

단방향 매핑 후 양쪽을 서로 참조할 수 있도록 상대 객체에도 매핑을 해주면 된다.

 

Team 객체에서 바라보면 일대다(1 : N)이기 때문에 @OneToMany를 붙여준다.

@Entity
@Getter
@Setter
public class Team {
    @OneToMany(mappedBy = "team")
    private List<Member> members = new ArrayList<>();
}

mappedBy로 상대 객체에 있는 자신과 매핑 해주면 된다.

 

그리고 Member(N) : Team(1)에서 Member가 Team 객체를 갖는 것처럼 Team에도 List<Member>를 넣어준다.

 

 

사실, 단방향 매핑만으로도 이미 연관관계 매핑은 끝났다.

 

실질적으로 외래키를 갖고 관리하는 쪽은 Member고 테이블에서 값을 조회할 때도 외래키 하나만 있으면 가능하다.

 

그런데도 양방향으로 매핑을 해주는 이유는, 조금 더 객체지향적으로 설계하여 상대 객체에서도 값을 조회하기 위해서라고 봐도 된다.

 

 

한 가지 팁을 드리자면 mappedBy는 주인이 아닌 쪽에, JoinColumn은 주인인 쪽에 붙이는 것으로 외워서 사용하면 편하다.