연관관계 매핑 기초
객체를 테이블에 맞춰 모델링
만약 객체를 테이블과 똑같이 모델링 하면 어떻게 될까요? 데이터베이스에는 아래와 같이 team과 member가 1대다 연관관계를 갖으면서 member쪽에 team_id가 foreign key로 등록이 됩니다.
Member모델에 teamId를 넣어주면서 테이블과 같이 모델링을 해줬습니다.
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
@Column(name = "TEAM_ID")
private Long teamId;
...
}
@}Entity
public class Team {
@Id @GeneratedValue
private Long id;
private String name;
...
}
만약 멤버의 team을 조회해보도록 하겠습니다. findTeam을 할때 참조를 바로 이용하는게 아니라 저장된 teamId를 이용해서 id값에 맞는 팀을 조회해올 수 밖에 없으므로 객체지향적인 방법이라고 보기 어렵습니다.
//팀 저장
Team team = new Team();
team.setName("TeamA");
em.persist(team);
// 회원 저장
Member member = new Member();
member.setName("member1");
member.setTeamId(team.getId());
em.persist(member);
// 멤버의 팀 조회
Member findMember = em.find(Member.class, member.getId());
Team findTeam = em.find(Team.class, findMember.getTeamId());
객체지향적 모델링 : 연관관계
그렇다면 테이블과 똑같이 모델링 했음에도 이렇게 되는 이유가 무엇일까요?
그 이유는 테이블은 외래 키(Fk)로 조인을 해서 연관테이블을 찾아오지만 객체는 참조를 해서 연관 객체를 찾아와야하는 차이때문입니다. 즉 객체지향적으로 모델링하기위해서는 아래와 같이 Member안에 **team이라는 객체**가 들어있어야 합니다. 그래야 참조를 바로 할 수 있기 때문입니다.
아래와 같이 Member 클래스안에 team을 만들어줍니다. 그리고 @ManyToOne 어노테이션을 붙여서 Member입장에서 연관관계를 써줍니다(다대일). 그리고 이때 JoinColumn으로 TEAM_ID를 넣어줘서 조인할때 FK로 쓸 값을 정해줍니다.
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
이전과는 다르게 setTeam을 통해 team객체를 넘겨주면 알아서 teamId를 찾아 FK값으로 쓰고 연관관계를 설정해줍니다.
//팀 저장
Team team = new Team();
team.setName("TeamA");
em.persist(team);
//회원 저장
Member member = new Member();
member.setName("member1");
member.setTeam(team); //단방향 연관관계 설정, 참조 저장
em.persist(member);
이로인해 아래와 같이 이제 team을 getTeam을 이용해서 바로 참조로 가져올 수 있습니다.
Team findTeam = findMember.getTeam();