인프런 김영한 강사님의 [자바 ORM 표준 JPA 프로그래밍 - 기본편] 을 수강하고 정리한 글입니다.
📌 연관관계 매핑 시 고려사항 3가지
✅ 다중성
다대일 (@ManyToOne), 일대다 (@OneToMany), 일대일 (@OneToOne), 다대다 (@ManyToMany)
'대' 를 기준으로 앞에있는 곳을 연관관계의 주인으로 한다.
그곳이 외래 키의 위치기 때문.
✅ 단방향, 양방향
- 객체
- 참조용 필드가 있는 쪽으로만 참조가 가능하다.
- 한 쪽만 참조하면 단방향, 양쪽이 서로 참조하면 양방향.
- 테이블
- 외래 키 하나로 양쪽 모두 조인 가능
- 방향 개념이 없다.
✅ 연관관계의 주인
객체 양방향 관계는 참조가 2군데이므로, 둘 중 테이블의 외래 키를 관리할 곳을 지정해야 하는데, 그 곳을 연관관계의 주인이라고 한다.
연관관계의 주인은 외래 키를 관리하고, 그 반대편은 외래 키에 영향을 주지 않고 조회만 가능하다.
📌 다대일 [N:1]
✅ 다대일 단방향
가장 많이 사용하는 연관관계이다.
✅ 다대일 양방향
외래 키가 존재하는 곳이 연관관계의 주인이다.
양쪽을 서로 참조할 수 있도록 개발하면 된다.
📌 일대다 [1:N]
✅ 일대다 단방향
실무에서는 권장하지 않는 모델이다.
일대다 단방향에서는 일(1)이 연관관계의 주인인데, 테이블 관점에서는 항상 다(N)쪽에 외래 키가 존재한다.
객체와 테이블의 이러한 차이 때문에 반대편 테이블의 외래 키를 관리하게 되는 특이한 구조다.
@JoinColumn 을 반드시 사용해야 한다. 그렇지 않으면 중간에 별도의 조인 테이블이 필요하다.
일대다의 경우, update 쿼리가 반드시 나가는데, 다른 테이블에 외래키가 존재하기 때문이다.
이러한 이유들로 일대다 단방향 매핑 보다는, 다대일 양방향 매핑을 권한다.\
✅ 일대다 양방향
공식적으로 존재하지 않는 매핑이다.
이 매핑을 위해서는 아래 설정이 필요하다.
@JoinColumn(insertable = false, updatable = false)
읽기 전용 필드를 사용해서 양방향처럼 사용하는 방식인데, 이 방식 보다는 다대일 양방향을 권한다.
📌 일대일 [1:1]
✅ 일대일 : 주 테이블에 외래 키 단방향
다대일 (@ManyToOne) 단방향 매핑과 유사하다.
✅ 일대일 : 주 테이블에 외래 키 양방향
다대일 양방향 매핑과 마찬가지로 외래 키가 존재하는 곳이 연관관계의 주인이다.
그리고 주인의 반대 편은 마찬가지로 mappedBy를 적용한다.
✅ 일대일 : 대상 테이블에 외래 키 단방향
공식적으로 지원하지 않는 매핑 방식이다.
양방향은 지원한다.
✅ 일대일 : 대상 테이블에 외래 키 양방향
일대일 주 테이블에 외래 키 양방향 방식과 매핑 방법은 같다.
✅ 일대일 매핑 정리
두 가지가 있었다. 주 테이블에 외래 키 vs 대상 테이블에 외래 키
- 주 테이블에 외래 키
- 객체 지향 개발자가 선호하는 방식
- JPA 매핑이 편리하다.
- 이 방식을 권장한다.
- 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인 가능하다는 장점이 있다.
- 값이 없으면 외래 키에 null을 허용하게 되는 단점이 있다.
- 대상 테이블에 외래 키
- DB 개발자가 선호하는 방식
- 주 테이블과 대상 테이블을 일대일에서 일대다 관계로 변경할 때 테이블 구조를 그대로 유지하기 좋다는 장점이 있다.
- JPA가 제공하는 기본 프록시 기능의 한계로 인해, 지연 로딩으로 설정하더라도 항상 즉시 로딩되는 단점이 있다.
📌 다대다 [N:M]
✅ 다대다 매핑
RDBMS에서는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없다.
두 테이블 중간에 연결 테이블을 추가하여 일대다, 다대일 관계로 풀어내야 한다.
객체 관점에서는 컬렉션을 사용하여 객체 2개로 다대다 관계를 표현하는 것이 가능하다.
위 방식은 결국 @ManyToMany 키워드를 사용한다.
@JoinTable로 연결 테이블을 지정한다.
✅ 다대다 매핑의 한계
객체 관점에서만 보면 편리해보인다.
그런데 실무에서는 사용할 수 없다.
내가 생각하지 못했던 이상한 쿼리가 발생할 수 있다.
✅ 다대다 한계 극복
결국 연결 테이블용 엔티티 추가해야 한다.
연결 테이블을 연결 엔티티로 승격시켜야 한다는 뜻이다.
@ManyToMany를 @OneToMany, @ManyToOne 두 가지로 나누어 사용해야 한다.
'Backend > JPA' 카테고리의 다른 글
[자바 ORM 표준 JPA 프로그래밍 - 기본편] 8. 프록시와 연관관계 관리 (0) | 2024.01.05 |
---|---|
[자바 ORM 표준 JPA 프로그래밍 - 기본편] 7. 고급 매핑 (0) | 2024.01.04 |
[자바 ORM 표준 JPA 프로그래밍 - 기본편] 5. 연관관계 매핑 기초 (0) | 2024.01.04 |
[자바 ORM 표준 JPA 프로그래밍 - 기본편] 4. 엔티티 매핑 (0) | 2024.01.04 |
[자바 ORM 표준 JPA 프로그래밍 - 기본편] 3. 영속성 관리 - 내부 동작 방식 (0) | 2024.01.04 |
개발자가 되고 싶어요.