객체와 관계형 데이터베이스 테이블을 어떻게 매핑할지 이다.
(목적: 객체 지향 프로그래밍과 데이터베이스 사이의 패러다임 불일치를 해결하는 것)
DB 테이블은 외래 키 하나로 양 쪽 테이블 조인이 가능하다. (다리 역할)
아래 그림 예시를 보면 TEAM과 MEMBER는 1대 다 관계를 가지고 있고 MEMBER에서 TEAM의 ID를 외래키로 가지고 있다.
// 내가 속한 팀 찾기
SELECT *
FROM TEAM A INNER JOIN MEMBER B
ON A.ID = B.TEMA_ID
// 팀에 속한 멤버 찾기
SELECT *
FROM MEMBER A INNER JOIN TEAM B
ON A.TEAM_ID = B.ID
sql
class Member{
Team tema1;
}
class Team {}
class Member{
Team tema1;
}
class Team {
Member member1;
}
객체를 양방향 연관 관계로 만들면 연관 관계의 주인을 지정해야 한다.
객체 연관관계
테이블 연관관계
객체 연관 관계를 단방향으로 매핑했을 때는 참조를 하나만 사용하기 때문에 연관 관계 주인 필요 없다.
하지만 양방향 관계로 매핑해버리면 참조가 2곳이 된다. (JPA는 혼란 - 패러다임 불일치)
JPA에서는 두 객체 연관 관계 중 하나를 정해 테이블의 외래키를 관리해야 한다. (연관 관계의 주인)
연관관계 주인만이 데이터베이스 연관관계와 매핑되고 외래 키를 관리(등록, 수정, 삭제)할 수 있다.
주인이 아닌 쪽은 읽기만 할 수 있다.
=> 연관 관계의 주인은 외래 키가 있는 쪽으로 설정
=> Member 엔티티에서 Team_id를 외래키로 가지고 있기 때문에 Member를 주인으로 설정해야 한다!
데이터베이스를 기준으로 다중성을 결정한다.
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "MEMBER_NAME", nullable = false)
private String NAME;
@ManyToOne // 멤버 N : 팀 1
@JoinColumn(name = "TEAM_ID")
private Team team; // Team 자체를 참조
}
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "MEMBER_NAME", nullable = false)
private String NAME;
}
@Entity
public class Team {
@Id @GeneratedValue
private Long id;
@Column(name = "TEAM_NAME", nullable = false)
private String name;
@OneToMany
@JoinColumn(name="MEMBER_ID")
private List<MEMBER> members = new ArrayList<>();
}
말그대로 하나랑 하나가 매칭되는 것이므로 어느 쪽에 외래키를 설정하든 문제는 없다.
실무에서 보통 사용 금지라고 한다.