개발/JPA

[JPA 기본] 6. 다양한 연관관계 매핑

Dahee Joy Cha 2022. 1. 22. 03:36

연관관계 매핑시 고려사항 3가지

1. 다중성

예) ManyToOne, OneToMany, OneToOne, ManyToMany

2. 단방향인지 양방향인지

3. 연관관계의 주인 

 

다중성

- 주의: ManyToMany는 실무에서 쓰면 안된다. 

- ManyToOne, OneToMany를 주로 쓰며, OneToOne은 가끔 나온다.

 

양방향 vs 단방향

- 테이블은 외래 키 하나로 양쪽 조인 한다. 따라서 방향이라는 개념이 없다. 

- 반면 객체는 참조용 필드로 참조 가능. 따라서 방향 개념 존재 (양방향, 단방향) 

 

연관 관계의 주인

객체 2개가 양방향 관계를 맺을 때, 둘 중 테이블의 외래키를 관리할 곳을 찾아야 함. 

- 주인 : 외래 키를 관리

- 주인 반대편: 외래 키 영향 x. 단순 조회만 가능.

 

1. 다대일

 'Many'가 주인

 

다대일 단방향

- 가장 많이 사용하는 연관관계. 

- e.g.Member-Team의 관계에서 Member가 Many. 따라서 Member의 team이 주인이다.

 

다대일 양방향. 

- Member만 Team을 포함하고, Team은 멤버를 조회할 수 없는 것이 기존의 '다대일 단방향' 연관관계. '다대일 양방향 관계'에서는  이 때, Team이 members를 포함하여도 테이블에는 영향을 끼치지 않는 것이 핵심. 

 

2. 일대다

-  정의: 1:다 관계에서 일(1)이 연관관계의 주인 (예. Team.members가 주인)

- 사용예시: Teeam은 members를 알고 싶은데, member에서는 Team에 대한 정보가 필요 없을 때

- 주의: 테이블에선 무조건 Many에 외래키 들어간다. 

- 주의: @JoinColumn을 꼭 사용하자. 그렇지 않으면 조인 테이블 방식이 사용됨. (중간에 테이블 하나 추가)

- 권장되는 모델링 방법은 아님. (실무에서 거의 안 씀)

 

2.1 일대다의 단점

- 엔티티의 외래키가 다른 테이블에 있다. (meber에 외래키 있는데, Team이 주인을 가지면 헷갈림)

- 연관관계 관리 위해 update 쿼리 추가 실행 (member insert, team insert, member update)

- team만 손댄 것 같은데, member도 업데이트 된다. (운영시 헷갈림)

 

2.2 결론

권장되는 전략 : 일대다 단방향 매핑보다는 다대일 양방향 매핑을 사용하자. 

 

2.3 참고: 일대다 양방향

- JPA 스펙에서 공식적으로 존재하지 않는다. 꼼수를 아래처럼 쓸 수는 있다. 

- @JoinColumn(insertable=false, updatable=false)를 통해 읽기 전용 필드 생성. 

- 일대다 양방향은 쓰지말자.. 다대일 양방향을 사용하자...

 

3. 일대일 (1:1)

- 주 테이블(=주로 엑세스하는 테이블)대상 테이블 중 외래키 넣을 곳 선택 가능

- 실무에서 강사님은 주테이블에 FK를 넣음. (Member 뒤진 다음 Locker 뒤질 필요 x) >> DBA와 협의 필요. 

- 외래 키에 데이터 베이스 유니크 제약 조건 추가

  ( 유니크 제약 조건 없으면 한 쪽이 Many가 될 수 있으므로 꼭 필요)

- 예) Member - Locker 관계 (1명에게 사물함 한 개 배정)

- 일대일 단방향, 일대일 양방향

 

주의!!!!

** 일대일 대상테이블에 외래키 단방향은 불가능. ('일대일' 강의 7:11)

** 대상 테이블에 외래키 양방향은 가능. ('일대일' 강의 14:19)

-> 일대일 정리 PPT 정리 상세 내용 참고할것.  (외래키를 주테이블 / 대상 테이블에 둘 경우에 대해 장단점 나옴)

 

4. 다대다 

- 실무에서 절대로 쓰면 안된다. 

- 관계형 데이터 베이스는 정규화된 테이블 2개로 다대다 관계 표현 불가능. 연결 테이블 통해 일대다, 다대일 관계로 풀어냄.

   : 예) Member - Member_Product - Product

 

- 다:다의 한계 어떻게 극복할까?

  -> 연결 테이블용 엔티티 추가(연결 테이블을 엔티티로 승격)

  -> 강의 10:32 

 

- Member_Product 테이블에서 Member_ID와 Product_ID를 함께 사용하여 Composite Primary key로 사용하는 경우도 있다.  하지만 유연성을 위해 composite PK보다는 의미 없는 값 (예. auto generated value) 하나를 PK로 쓰자. (다:다 강의 12:58)