티스토리 뷰
객체의 참조와 테이블의 외래 키를 매핑하는 방법에 대해서 알아보자.
Base
가령, 다음과 같은 요구사항이 있다고 가정해보자.
1. 회원과 팀이 있다.
2. 회원은 하나의 팀에만 소속될 수 있다.
3. 회원과 팀은 다대일 관계다.
관계형 DB의 경우에서 위 예시를 매핑하기 위해서는 아래와 같이 MEMBER 테이블에서는 외래 키를 가지고 있어야 한다. 그래서 이러한 구조를 그대로 객체로 옮겨오게 되면 Member Entity에는 teamId를 가지고 있어야 하는데,
이것은 객체지향적인 설계에 어긋난다.
코드로 풀어서 살펴보면,
// 회원을 저장하는 경우 (외래키 식별자를 직접 다룸)
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setUsername("member1");
member.setTeamId(team.getId());
em.persist(member);
// 조회하는 경우
Member findMember = em.find(Member.class, member.getId());
Long findTeamId = findMember.getTeamId();
Team findTeam = em.find(Team.class, findTeamId);
보는 바와 같이 객체지향적인 방법으로 조회할 수 없다.
즉, 테이블은 외래 키로 조인을 사용하고, 객체는 참조를 사용하는 구조적인 문제로 인해서 객체를 테이블에 맞춰서 데이터 중심으로 설계하면 협력 관계를 만들 수 없게 된다.
Mapping
바로 위에서 언급한 이유로 객체의 연관관계를 사용하여 매핑을 해야 한다.
위 그림처럼 Member Entity에 TeamId가 아닌 Team 자체를 매핑시켜준다.
이때, 중요한 것이 Member 입장에서 생각했을 때 하나의 Team에 여러 Member가 소속된다는 점이다.
즉! Member가 다수 그리고 Team이 1, N 대 1 관계가 성립된다.
이것을 JPA에서는 앞에 오는 위치가 본인을 가리키도록 하여서, Member 입장에서는 Team과 다수(N) 대 일의 관계를 가지므로, @ManyToOne 이라는 Annotation을 제공한다.
또한, 이런 관계를 명시해주었을 때, Team이라는 객체와 Member 테이블의 외래 키인 특정 컬럼을 매핑해주어야 한다고 JPA에게 명시해주어야 한다. 이것을 JPA에서는 @JoinColumn 이라는 Annotation을 제공하고 있다. 해당 Annotation의 속성 값 name에 해당하는 컬럼을 명시하여 주면, 객체의 연관관계를 사용한 매핑이 완성된다.
@Entity
public class Member {
public Member() {
}
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String username;
// @Column(name = "TEAM_ID")
// private Long teamId;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
// getter setter
}
'프로그래밍 > JPA' 카테고리의 다른 글
양방향 연관관계 매핑 (0) | 2021.04.27 |
---|---|
Entity 매핑하기 (0) | 2021.04.26 |
영속성 컨텍스트 (0) | 2021.04.24 |
Hello JPA (0) | 2021.04.21 |
왜 JPA인가? (0) | 2021.04.21 |