DB 에서는 테이블의 외래키를 이용하여 테이블간의 연관관계를 구성한다. JPA 는 전통적인 테이블 간의 관계를 객체간의 연관관계로 매핑시켜준다. 객체의 참조변수와 테이블의 외래키를 매핑시켜서 연관관계를 객체지향적으로 변환시켜준다.
JPA 에서 연관관계는 방향에 따라서 단방향, 양방향으로 구분이 되며, 서로의 연관을 가지는 객체의 개수 (다중성, multiplicity) 에 따라서 다대일, 일대다, 일대일, 다대다 등으로 구분이 된다.
또한 양방향 연관관계에서 연관관계의 주인, owner 를 지정하여 어떤 객체가 해당 데이터의 관리 권한을 가질 것인가를 결정한다.
1. 연관관계의 필요성
객체의 연관관계가 없이 테이블의 연관관계를 기반으로 설계를 하게되면 객체지향적인 설계를 할 수가 없어진다.
테이블은 외래키를 통해서 참조를 하는데, 이를 기반으로 설계를 하면 객체에서도 참조를 하는 쪽에서 해당 외래키에 해당하는 멤버 변수를 가져서 참조하도록 해야한다. 이러한 경우, 참조를 하는 쪽에서 참조하고 있는 객체를 조회하기 위해서는 외래키에 해당하는 참조를 사용해야 한다. 참조하는 객체에서 바로 조회하지 못하고 외래키 참조 (식별자) 를 통해 반대편 객체를 다시 조회해야 한다.
객체를 테이블에 맞추어서 데이터 중심으로 설계를 하면 객체간의 협력관계를 구성할 수 없다. 이러한 설계는 객체지향적이지 못하다. 이러한 문제를 해결하기 위해서 객체간의 연관관계 매핑을 사용하여 객체간의 협력관계를 구성한다.
class Team {
@Id @GeneratedValue
private Long id;
// ...
}
class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "TEAM_ID")
private Long teamId; // Team 의 id 를 외래키로 참조한다.
// ...
}
public class Test {
public static void main(String[] args) {
// ...
Team team = new Team();
em.persist(team);
Member member = new Member();
member.setTeamId(team.getId()); // Team 의 id 를 지정한다.
em.persist(member);
// 조회시에 member 에서 team 을 바로 조회하지 못하고 다시 Entity 조회를 수행한다.
Member findMember = em.find(Member.class, member.getId());
Long findTeamId = findMember.getTeamId();
Team findTeam = em.find(Team.class, findTeamId);
// ...
}
}
객체와 테이블의 차이
- 테이블: 테이블의 외래키로 조인하여 연관된 테이블을 조회한다.
- 객체: 연관관계를 매핑한 참조를 통해서 연관된 객체를 조회한다.
2. 단방향 연관관계
단방향 연관관계는 한 객체가 다른 객체를 참조하는 것이다.
연관관계를 객체지향적으로 설계하면 테이블 기준과 같이 외래키 멤버를 참조하는 것이 아니라 객체 자체를 참조한다. 테이블의 외래키와 객체의 참조가 매핑되는 것이다.
아래의 예시를 보면 이전의 테이블 기준의 연관관계와 달리 참조하는 객체에서 참조되는 객체를 바로 조회할 수 있다. 테이블 기준의 데이터 연관관계는 외래키 멤버를 참조하였다면, 객체 기준의 연관관계의 예시에서는 참조되는 테이블의 객체를 참조한다. 이러한 참조를 테이블의 외래키와 매핑하여 연관관계를 구성한다.
class Team {
@Id @GeneratedValue
private Long id;
// ...
}
class Member {
@Id @GeneratedValue
private Long id;
@ManyToOne // 다대일 관계
@JoinColumn(name = "TEAM_ID") // 외래키 team_id 와 객체 참조가 매핑된다.
private Team team;
// ...
}
public class Test {
public static void main(String[] args) {
// ...
Team team = new Team();
em.persist(team);
Member member = new Member();
member.setTeam(team); // Team 객체를 참조로 저장한다.
em.persist(member);
// 조회시에 member 에서 team 참조를 통해서 바로 조회할 수 있다.
Member findMember = em.find(Member.class, member.getId());
Team findTeam = findMember.getTeam(); // entity manager 를 거치지 않고 바로 조회가 가능하다.
// ...
}
}
'Tech > JPA' 카테고리의 다른 글
[JPA] 프록시와 지연로딩 (0) | 2022.05.23 |
---|---|
[JPA] 상속관계 매핑 (0) | 2022.05.23 |
[JPA] 연관관계 매핑 종류 (0) | 2022.05.17 |
[JPA] 연관관계 매핑 (2) - 양방향 연관관계 (0) | 2022.05.11 |
[JPA] 영속성 관리 (0) | 2022.05.09 |