데이터베이스의 경우에는 테이블 외래키를 통해 관계를 정의한다.
JPA는 데이터베이스 연관관계를 객체의 참조를 통해 구현한다.
이번 포스팅에서는 객체 연관관계와 테이블 연관관계의 차이를 분명히 알 수 있도록 작성하고자 한다.
이전 강의들을 배우면서 JPA는 객체 중심의 기술이라는 것을 알 수 있었다.
하지만 한번 JPA의 특징인 객체의 관점으로 사용해보지 않고, 테이블 연관관계 매핑방식인 외래키를 사용하여 연관관계 정보를 가져오는 예제를 살펴보면서 비교를 시작해보자.
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String name;
@Column(name = "TEAM_ID")
private Long teamId;
// Getter & Setter...
}
@Entity
public class Team {
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
// Getter & Setter...
}
Entity를 다음과 같이 만들고 관계를 설정하려면 아래와 같이 코드를 짤 수 있다.
//팀 저장
Team team = new Team();
team.setName("TeamA");
em.persist(team);
//회원 저장
Member member = new Member();
member.setName("member1");
member.setTeamId(team.getId()); // team_id 저장! (연관 관계 매핑), 애매한 부분!
em.persist(member);
테이블엔 예상한 대로 외래키(FK) TEAM_ID
가 잘 삽입(INSERT) 된다.
이제 멤버를 가져와서 다시 또 팀 find하여 가져오는 경우의 코드를 한번 살펴보자.
Member findMember = em.find(Member.class, member.getId()); // 1. Member 객체를 가져온다.
Long findTeamId = findMember.getTeamId(); // 2. Team_id를 가져온다.
Team findTeam = em.find(Team.class, findTeamId); // 3. Team객체를 가져온다.
뭔가... 객체로 값을 가져오긴 하지만 굳이 이럴꺼면 JPA를 왜쓸까? 라는 생각이 든다
그렇다. 이렇게 JPA를 사용할 거면 굳이 객체 참조 연관관계라는 수식어가 필요없을 것 같다. 테이블은 외래키 조인으로 데이터를 가져오지만 JPA 방식인 객체 참조 방식을 사용하여 연관된 객체를 찾는다. 이게 핵심이며, 정말 테이블, 객체 관계의 패러다임이 완전히 다른 것이다.
앞서 예제에서 사용한 테이블 매핑 방식이 아닌 객체 참조 방식을 사용하기 위해 단방향 매핑에 대해 살펴보자.
@Entity
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
// Getter & Setter ...
}
@Entity
public class Team {
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
// Getter & Setter ...
}
아래와 같이 setTeam(team)
으로 객체 연관관계가 지정된다.
//팀 저장
Team team = new Team();
team.setName("TeamA");
em.persist(team);
//회원 저장
Member member = new Member();
member.setName("member1");
member.setTeam(team);
em.persist(member);
테이블엔 예상한대로 외래키(FK) TEAM_ID
가 잘 삽입(INSERT)된 것을 확인할 수 있다.
이제 다시 한번 멤버가 속한 팀의 정보를 가져오는 코드를 살펴보자.
Member findMember = em.find(Member.class, member.getId()); // 1. Member 객체를 가져온다.
Team findTeam = findMember.getTeam(); // 2. 이렇게 객체를 바로 가져올 수 있다.
위에서 보았던 예제와 다른 점을 확인해볼 수 있다.
Member을 찾고, team_id를 꺼내서 다시 Team 객체를 찾는 과정과 달리 @ManyToOne
을 사용해서 외래키 삽입(INSERT)할수도 있고, Team 객체를 find하여 가져올 수 있다.
Member findMember = em.find(Member.class, member.getId());
Team findTeam = findMember.getTeam();
Team newTeam = em.find(Team.class, 100L);
findMember.setTeam(newTeam); // 연관 관계 수정!
다음 위 예제를 살펴보면서
TEAM_ID를 FK 외래키로 두어 테이블 연관관계 매핑 방식과
JPA방식인 Team 객체를 통해 객체 연관관계 매핑 방식을 비교해볼 수 있었다.
@ManyToOne
어노테이션을 사용하여 단방향 매핑을 만들 수 있었고 테이블에 연관이 지어져 데이터 삽입(INSERT), 데이터 조회(SELECT) 해올 수 있는 것을 확인해보았다.
김영한님 ORM 표준 JPA프로그래밍 강의를 듣고 공부한 내용을 정리하고자 작성하였습니다.
문제가 될시 삭제하겠습니다. 🙂