1. 개요


이전 포스팅에서 객체 연관관계에서의 단방향 관계, 양방향 관계에 대해 살펴봤습니다.
이제 DB 테이블 기준으로 경우의 수를 나눠서 생각해보겠습니다. DB 테이블의 관계는 총 4가지로 나뉩니다.

  • 다대일 N:1
  • 일대다 1:N
  • 일대일 1:1
  • 다대다 N:M

위 관계는 좌측 테이블을 기준으로 잡고 좌측에 외래 키가 있는 경우를 나타냈습니다.
예를 들어, N:1 관계는 N쪽에 외래 키가 있는 경우고, 1:N 관계는 1쪽에 외래 키가 있는 경우입니다.

위와 같은 4개의 DB 테이블 관계에 대해 나눠서 살펴보겠습니다.

[그림 1] 4개의 관계에 대한 객체 연관관계를 나눠보기

2. N:1


이전 포스팅에서도 살펴봤듯이, 가장 일반적이고 대표적이고 직관적인 모델입니다.
아래 N:1 테이블을 기준으로 설명하겠습니다.

[그림 2] N:1 관계 예시 테이블

두 가지 경우로 나눠보겠습니다.

  1. Member->Team 으로 가는 단방향
  2. Member<->Team 으로 가는 양방향

단방향은 Member Entity 클래스에 다음과 같이 Team 필드를 추가해주면 됩니다.

@Entity
public class Member {
    ... 생략
    
    @ManyToOne
    @JoinColumn(name = "team_id")
    private Team team;
}

Member와 Team 테이블의 관계에서 외래 키가 N쪽인 Member에 있기 때문에 직관적이고 쉽습니다.
만약 양방향으로 만들고 싶다면 이전 포스팅에서 살펴봤듯이 Team Entity 클래스쪽에 @OneToMany와 mappedBy 속성으로 연관관계의 주인(해당 필드와 관계를 맺는 외래 키와 매핑되는 타 테이블에 있는 필드)을 명시해주면 됩니다.

@Entity
public class Team {
    ... 생략
    
    @OneToMany(mappedBy = "team")
    private List<Memeber> members = new ArrayList<>();
}

3. 1:N


이 모델은 위 처럼 N쪽에 외래 키가 있는게 아니라, 1쪽에 외래 키가 있는 형태입니다.

[그림 3] 1:N 관계 예시 테이블

기준 테이블이 Member인 상황에서 외래 키가 타 테이블에 있기 때문에 Member를 수정하면 Team 테이블의 값이 수정됩니다.
그리고 무엇보다 1:N 관계에서 DB는 무조건 N쪽에 외래 키를 두기 때문에 해당 모델은 적절치 못한 모델입니다.
따라서 1:N 단방향 매핑을 사용해야할 일이 있다면, 차라리 N:1 양방향 매핑을 고려하는 것이 권장됩니다.

4. 1:1


Member와 Locker(사물함)을 예시로 들어보겠습니다.

[그림 4] 1:1 관계 예시 테이블

위와 같은 상황에서 Member->Locker로 가는 단방향은 간단합니다.

@Entity
public class Member {
    ... 생략 
    
    @OneToOne
    @JoinColumn(name = "lockerId")
    private Locker locker;
}

그리고 Member<->Locker로 양방향으로 하고 싶다면 Locker 클래스에도 @OneToOne과 mappedBy 속성을 추가합니다.

@Entity
public class Locker {
    ... 생략
    
    @OneToOne(mappedBy = "locker")
    private Member member;
}