본문 바로가기

자바 ORM 표준 JPA 프로그래밍

연관관계 매핑 기초

- 목표

1) 객체와 테이블 연관관계의 차이를 이해

2) 객체의 참조와 테이블의 외래 키를 매핑

 

- 용어 이해

1) 방향: 단방향, 양방향

2) 다중성: 다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(N:M) 이해

3) 연관관계의 주인: 객체 양방향 연관관계는 

 

1) 연관관계가 필요한 이유

객체지향 설계의 목표는 자율적인 객체들의 
협력 공동체를 만드는 것이다.

(1) 예제 시나리오

- 회원과 팀이 있다

- 회원은 하나의 팀에만 소속될 수 있다

- 회원과 팀은 다대일 관계다.

 

(2) 객체를 테이블에 맞추어 모델링

import java.persistence.*;


@Entity
public class Member{

    @Id @GeneratedValue
    private Long id;
    
    @Column(name = "USERNAME")
    private String username;
    
    @Column(name = "TEAM_ID")
    private Long teamId;
}
import javax.persistence.Entity;

@Entity
public class Team{

    @Id
    @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;
    private String name;

}

- 객체를 테이블에 맞추어 데이터 중심으로 모델링하면, 협력 관계를 만들 수 없다

(1) 테이블은 외래 키로 조인을 사용해서 연관된 테이블을 찾는다

(2) 객체는 참조를 사용해서 연관된 객체를 찾는다.

(3) 테이블과 객체 사이에는 이런 큰 간격이 있다. 

 

2) 단방향 연관관계

import java.persistence.*;


@Entity
public class Member{

    @Id @GeneratedValue
    private Long id;
    
    @Column(name = "USERNAME")
    private String username;
    
    @ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private Team team; 
}

 

3) 양방향 연관관계와 연관관계의 주인

- 테이블의 연관관계는 외래키 하나로 양방향이 다 있습니다.

  즉, 테이블의 연관관계는 방향이라는 개념이 없습니다.

import javax.persistence.Entity;

@Entity
public class Team{

    @Id
    @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;
    private String name;
    
    @OneToMany(mappedBy = "team")
    private List<Member> members = new ArrayList<>();

}

- 양방향 매핑이 좋냐에 대해서는,

  객체는 가급적이면 단방향이 좋다. 

 

(1) mappedBy

- mappedBy를 이해하려면 객체와 테이블간에 연관관계를 맺는 차이를 이해해야 합니다. 

(1-1) 객체와 테이블이 관계를 맺는 차이

- 객체 연관관계  = 2개

(1) 회원 -> 팀 연관관계 1개(단방향)

(2) 팀 -> 회원 연관관계 1개(단방향)

- 테이블 연관관계 = 1개

(1) 회원 <-> 팀의 연관관계 1개(양방향) 

 

- 객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계 2개입니다. 

-> 즉, 객체를 양방향 참조로 만들려면 단방향 연관관계를 2개 만들어야 합니다. 

 

- 반면, 테이블은 외래 키 하나로 두 테이블의 연관관계를 관리합니다.

-> MEMBER.TEAM_ID 외래 키 하나로 양방향 연관관계를 가집니다.(양쪽으로 조인할 수 있습니다.)