다대다
• 관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없다.
• 연결 테이블을 추가해서 일대다, 다대일 관계로 풀어내야한다.
• 보면 두 개의 PK가 묶여있는걸 알 수 있다.
• 객체는 컬렉션을 사용해서 객체 2개로 다대다 관계 가능
다대다 단방향
public class Member{
@ManyToMany
@JoinTable(name = "MEMBER_PRODUCT")
private List<Product> products = new ArrayList<>();
}
다대다 양방향
public class Member{
@ManyToMany
@JoinTable(name = "MEMBER_PRODUCT")
private List<Product> products = new ArrayList<>();
}
public class Product{
@ManyToMany(mappedBy = "products");
private List<Member> members = new ArrayList<>();
}
※참고로 @JoinTable은 다음과 같이 몇가지 더 추가해줘야한다.
@ManyToMany
@JoinTable(name = "MEMBER_PRODUCT",
joinColumns = @JoinColumn(name = "MEMBER_ID"), // 내가 조인하는 대상은 MEMBER_ID
inverseJoinColumns = @JoinColumn(name = "PRODUCT_ID") // 반대쪽이 조인하는 대상은 PRODUCT_ID
)
private List<Product> products = new ArrayList<>();
다대다 정리
• @ManyToMany 사용
• @JoinTable로 연결 테이블 지정
• 다대다 매핑: 단방향, 양방향 가능
다대다 매핑의 한계
• 편리해 보이지만 실무에서 절대 사용X
• 중간테이블이 숨겨져있기 때문에 쿼리를 예측할 수 없다.
• 중간테이블에 삽입할 pk 컬럼외에는 다른 컬럼을 추가할 수 없다.
(주문시간, 수량 같은 데이터가 들어올 수 있음)
다대다 한계 극복
• 연결 테이블용 엔티티 추가 (연결 테이블을 엔티티로 승격)
• @ManyToMany -> @OneToMany <- @ManyToOne
※ 위의 설계도에서는 Member에서만 MemberProduct 리스트를 참조하지만, 밑의 클래스는 Product도 MemberProduct 리스트를 참조한다.
public class MemberProduct{
...
@MnayToOne
@JoinColumn(name = "MEMBER_ID")
private Member member;
@ManyToOne
@JoinColumn(name = "PRODUCT_ID")
private Product product;
}
public class Member{
....
@OneToMany(mappedBy = "member")
private List<MemberProduct> memberProducts = new ArrayList<>();
}
public class Product{
...
@OneToMany(mappedBy = "product")
private List<MemberProduct> memberProducts = new ArrayList<>();
}
저자의 추천
• 전통적인 방식인 두 개의 PK를 묶는 것보단, 의미없는 값을 PK로 두고 FK를 두는게 낫다.
• JPA에서는 두 개의 PK를 묶을경우 Composite id를 만들어줘야하는게 귀찮기도 하고, 유연하지 못하다.
• 어플리케이션을 운영/유지보수 하다보면 비즈니스가 변화하거나 업데이트를 해줘야하는데 pk가 어디에 종속적이면
시스템을 유연하게 변경하기가 어려워진다.
결론 : id는 그냥 일관성있게 @GernerateValue 만 써라.
@JoinColumn
외래 키를 매핑할 때 사용
@ManyToOne - 주요속성
다대일 관계 매핑
※targetEntity는 몰라도 된다. (과거에 Generic이 없던 시절 필요했던 속성)
※@OneToMany는 mappedBy 속성이 있지만, @ManyToOne은 mappedBy 속성이 없다.
이 말은 @ManyToOne의경우 반드시 연관관계의 주인되어야한다는 뜻이다.
@OneToMany - 주요속성
다대일 관계 매핑
'JPA' 카테고리의 다른 글
JPA - @MappedSuperclass (0) | 2022.04.10 |
---|---|
JPA - 상속관계 매핑 (0) | 2022.04.10 |
JPA - 다양한 연관관계 매핑(3) : 일대일 [1 : 1] (0) | 2022.04.10 |
JPA - 다양한 연관관계 매핑(2) : 일대다 [1 : N] (0) | 2022.04.09 |
JPA - 다양한 연관관계 매핑(1) : 다대일 [N : 1] feat. 연관관계 매핑시 고려사항 (0) | 2022.04.09 |
댓글