[JPA] 다양한 연관관계 매핑
연관관계 매핑에 대한 기본 지식을 쌓았으니, 설계 시 만날 수 있는 다양한 연관관계들에 대해 살펴보자.
다대일 [N : 1]
연관관계 매핑의 기본이다.
테이블에서 FK를 가진 요소를 기준으로 매핑하고 그래프 객체 탐색이 필요한 경우 양방향으로 확장한다.
일대다 [1 : N]
다대일의 반대이다.
@JoinColumn 애너테이션을 사용하지 않으면 JoinTable 방식이 사용되니 주의하자.
(성능이 저하되고 운영이 어려워진다)
데이터베이스에서 외래 키는 다(多) 쪽에 위치한다.
다대일에서와 다르게 외래 키를 관리하는 엔티티가 Team에서의 List members이고, List를 변경하면 데이터베이스가 변경된다.
객체와 테이블의 차이 때문에 외래 키를 반대편 테이블이 관리하게 되는 특이한 구조가 됐다. -_-
Team 객체를 조작했는데 쿼리는 멤버 관련 쿼리가 날아간다.
실무에서는 데이터베이스 테이블이 수십개가 넘어가는데, 조작한 객체와 날아가는 쿼리가 일치하지 않으면 헷갈리기 쉽다.
따라서 실무에서는 이런 방식을 거의 사용하지 않고, 다대일 단방향 관계로 설계하고 필요 시 양방향 관계로 확장하는 방식으로 사용한다.
객체지향적으로는 조금 손해를 볼 수 있지만, 유지 보수 측면에서는 다대일 관계로 설계하는 편이 합리적이다.
일대일 [1 : 1]
일대일 관계에서는 참조를 어디에 넣을 지 선택해야 한다.
Member와 대응되는 Locker가 하나씩 있는 경우이다.
Member를 주 테이블로 생각하고 주 테이블에 외래 키를 넣은 일대일 관계이다.
@OneToOne 애너테이션을 사용하는 것 말고는 다대일 관계와 유사하다.
양방향을 추가할 때도 다대일에서 했던 작업과 비슷하게 수행하면 된다.
일대다 관계에서는 외래 키의 주인과 실제 외래 키 테이블이 어긋나는 경우를 지원하지만 일대일 관계에서는 지원하지 않는다.
위와 같이 대상 테이블에 외래 키가 있는 단뱡향 일대일 관계는 지원하지 않지만, 양방향 관계는 지원한다.
Locker에 있는 member를 연관관계의 주인으로 설정해버리면 된다.
사실 첫 번째 그림을 뒤집은것과 같다.
일대일 관계는 자신의 엔티티에 있는 외래 키는 자신이 직접 관리한다고 생각하자.
그러면 외래 키를 어디에 둬야 하는가가 문제인데..
나중에 하나의 Member가 여러 개의 Locker를 가질 수 있다면 Locker쪽에서 외래 키를 가지도록 설계하고 외래 키의 UNIQUE 조건을 풀어주면 된다.
데이터베이스를 관리하는 입장에서는 추후 변화에 대응하기 쉽도록 Locker쪽이 외래 키를 가지도록 설계하는 편이 합리적이지만...
개발자 입장에서 생각해보면 Member쪽이 외래 키를 가지도록 설계하는 편이 성능 측면에서 합리적이고, 좀 더 편하게 개발할 수 있다.
그때그때 상황에 맞춰서 괜찮은 방법으로 설계하자.
다대다 [N : M]
관계형 데이터베이스는 테이블 2개로 다대다 관계를 표현할 수 없으니, 중간에 연결 테이블을 추가해 1 : N M : 1 관계로 풀어서 사용해야 한다.
그런데 엔티티 객체를 다룰 때는 객체 2개로 다대다 관계를 표현할 수 있다.
@ManyToMany 애너테이션과 @JoinTable 애너테이션을 사용해 연결 테이블을 지정해서 사용하는데... 편해 보이지만 실무에서 사용하지는 않는다.
연결 테이블은 단순히 연결만 하고 끝나지 않는다.
연결 테이블에 매핑 정보만 들어가면 참 좋겠지만, 실무에서는 여러 가지 추가 정보가 들어가게 된다.
다대다 관계는 일대다 다대일 관계로 풀어내고 연결 테이블 역할을 하는 엔티티를 추가해서 풀어내야 한다.
연결 테이블을 엔티티로 관리하게 되면 매핑 정보 뿐만 아니라 다른 정보도 다룰 수 있어 다대다 문제를 깔끔하게 해결할 수 있다.
데이터베이스 테이블을 설계할 때 PK와 FK를 어떻게 설정할지는 좀 더 생각해 봐야 한다.
각각을 PK와 FK로 설정할지, PK를 별도로 만들어서 설정할지 정해야 하는데..
두 번째 방식을 사용하는 편이 개발할 때는 좀 더 편하다.
데이터베이스 테이블을 설계할 때는 어차피 다대다 관계를 풀기 위해 테이블을 하나 도입한다.
엔티티 객체를 설계할 때는 @ManyToMany 애너테이션으로 연결 테이블 없이 도입해도 되지만, 앞서 언급한
'Spring > JPA' 카테고리의 다른 글
[JPA] 프록시와 연관관계 (0) | 2022.12.24 |
---|---|
[JPA] 상속관계 매핑 (0) | 2022.12.23 |
[JPA] 연관관계 매핑 (0) | 2022.12.22 |
[JPA] 객체와 테이블 매핑 (0) | 2022.12.22 |
[JPA] 영속성 컨텍스트 (0) | 2022.12.21 |
댓글
이 글 공유하기
다른 글
-
[JPA] 프록시와 연관관계
[JPA] 프록시와 연관관계
2022.12.24 -
[JPA] 상속관계 매핑
[JPA] 상속관계 매핑
2022.12.23 -
[JPA] 연관관계 매핑
[JPA] 연관관계 매핑
2022.12.22 -
[JPA] 객체와 테이블 매핑
[JPA] 객체와 테이블 매핑
2022.12.22