다양한 연관관계 매핑

hyemin·2022년 1월 31일
0

JPA

목록 보기
5/7
post-thumbnail

다중성

연관관계는 아래와 같은 다중성이 있다.

  • 다대일 : @ManyToOne
  • 일대다 : @OneToMnay
  • 일대일 : @OneToOne
  • 다대다 : @ManyToMany

다대일과 일대다가 실무에서 가장 많이 쓰인다.

단방향, 양방향

객체는 참조용 필드가 있는 쪽으로만 참조가 가능하며, 한쪽만 참조하면 단방향, 양쪽이 서로 참조하면 양방향이다. (양방향은 단방향이 두 개 있는 것)

테이블은 외래 키 하나로 양쪽 조인이 가능하며, 방향이라는 개념이 없다.

연관관계의 주인

테이블은 외래 키 하나로 두 테이블이 연관관계를 맺지만, 객체 양방향 관계는 참조가 두 군데 이므로 둘 중 테이블의 외래 키를 관리할 곳을 지정해야한다.

  • 연관관계의 주인 : 외래 키를 관리하는 참조
  • 주인의 반대편 : 외래 키에 영향을 주지 않으며, 단순 조회만 가능하다.

다대일 [N:1]

다대일 단방향


가장 많이 사용하는 연관관계이며, 다대일의 반대는 일대다 관계이다.

다대일 양방향

앞의 것이 연관관계의 주인이라고 생각하자 (ex: 다대일이면 '다', 일대다면 '일')

  • 양방향 관계에서 외래 키가 있는 것이 연관관계의 주인이다.
  • JPA는 외래 키를 관리할 때 연관관계 주인만을 이용한다.
  • 양쪽을 서로 참조하도록 개발해야하며, 한 쪽만 참조하면 양방향 관계가 아니다.
  • 항상 양쪽을 서로 참조하도록 연관관계 편의 메서드를 만드는 것도 좋은 방법이다.

일대다 [1:N]

일대다 단방향


여기서는 '일'에 해당하는 Team이 연관관계의 주인이다.

  • 일대다 단방향은 일대다(1:N)에서 일(1)이 연관관계의 주인이다.
  • 테이블의 일대다 관계는 항상 다(N) 쪽에 외래 키가 있다.
  • 객체와 테이블의 차이 때문에 반대편 테이블의 외래 키를 관리하는 특이한 구조가 되어버린다.
  • @JoinColumn을 꼭 사용해야하며, 그렇지 않으면 조인 테이블 방식을 사용하여 중간에 테이블을 하나 추가하게 된다.

일대다 단방향 매핑의 단점

엔티티가 관리하는 외래 키가 다른 테이블에 있다는 것이 큰 단점이다.

외래 키가 다른 테이블에 있으므로, 연관관계 관리를 위해서는 추가로 UPDATE SQL을 실행하야한다.

  • 일대다 단반향 매핑보다는 다대일 양방향 매핑을 사용하는 것을 추천한다.

일대다 양방향


이런 매핑은 공식적으로 존재하지 않는다.
@JoinColumn(insertable=false, updatable=false)을 이용해 읽기 전용 필드를 사용해서 양방향 처럼 사용하는 것이다.
일대다 양방향도 마찬가지로 대신 다대일 양방향을 사용하도록 하자.

일대일[1:1]

일대일 관계

일대일 관계는 양쪽이 서로 하나의 관계만 가진다.
ex : 회원은 하나의 사물함만 사용하고, 사물함도 하나의 회원에 의해서만 사용되는 경우

  • 일대일 관계는 그 반대도 일대일이다.
  • 다대일 관계에서는 항상 '다' 쪽이 외래 키를 가졌지만 일대일 관계에서는 주 테이블이나 대상 테이블 중에 외래 키 선택 가능하다.
    • 주 테이블에 외래 키, 대상 테이블에 외래 키 두 경우가 가능하다.
    • 외래 키에 데이터베이스 유니크(UNI) 제약 조건을 추가해야한다.

주 테이블에 외래 키

개발자들은 주 테이블에 외래 키가 있는 것을 더 선호한다.
보통 비즈니스 로직에서는 주 테이블을 자주, 항상 조회하게 되므로 주 테이블만 확인하면 대상 테이블과 연관관계를 알 수 있기 때문이다.
이 때문에 일대일에 주 테이블에 외래 키가 있는 것이 사용하기 더 편리하기 때문이다.

주 테이블에 외래 키 : 단방향


서로 각각 하나만 가질 수 있다.

  • @OneToOne을 사용한다.
  • @ManyToOne(다대일) 단방향과 유사하다.

주 테이블에 외래 키 : 양방향


명확하게 일대일 관계일 경우 이 방식을 더 추천한다.

  • 양방향이므로 연관관계 주인을 정해야 한다.
  • 다대일 양방향 처럼 외래 키가 있는 곳이 연관관계의 주인이다.
  • 반대편은 mappedBy를 적용한다.

대상 테이블에 외래 키

대상 테이블에 외래 키 : 단방향

단방향 관계는 JPA에서 지원하지 않는다.

대상 테이블에 외래 키 : 양방향


일대일 주 테이블에 외래 키 양방향과 매핑 방법은 같다.
다만 대상 테이블에 외래 키가 있다는 것이 차이점이다.

일대일 정리

주 테이블에 외래 키

주 객체가 대상 객체의 참조를 가지는 것처럼 주 테이블에 외래 키를 두고 대상 테이블을 찾는다.

  • 이 방법은 객체 지향 개발자가 선호한다.
  • JPA 매핑이 편리하기 때문이다.
    장점 : 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인 가능하다.
    단점 : 값이 없으면 외래 키에 null을 허용한다.

대상 테이블에 외래 키

대상 테이블에 외래 키가 존재한다.

  • 전통적인 데이터베이스 개발자가 선호한다.
    장점 : 주 테이블과 대상 테이블을 일대일에서 일대다 관계로 변경할 때 테이블 구조를 유지한다.
    단점 : 프록시 기능의 한계로 지연로딩으로 설정해도 항상 즉시 로딩된다.

다대다[N:M]

이 방법은 실무에서 쓰지 않는다.
관계형 데이터베이스는 정규환된 테이블 두 개로 다대다 관계를 표현할 수 없다.

그래서 연결 테이블을 추가해서 일대다, 다대일 관계로 풀어낸다.
객체는 컬렉션을 사용해서 객체 두 개로 다대다 관계가 가능하다.

  • @ManyToMany를 사용한다.
  • @JoinTable로 연결 테이블을 지정한다.
  • 다대다 매핑은 단방향, 양방향 모두 가능하다.

다대다 매핑의 한계

편리해 보이지만 실무에서 사용하지 않는다.

그 이유는 연결 테이블이 단순히 연결만하고 끝나는게 아니며,예를 들어 위와 같이 주문시간, 수량과 같은 데이터가 들어올수 있다.

다대다 한계 극복

위와 같은 다대다 매핑의 한계를 극복하려면 연결 테이블용 엔티티를 추가하는 것이다.

  • 연결 테이블을 엔티티로 승격하는 것.
  • @ManyToMany를 @OneToMany, @ManyToOne으로 변경하는 것이다.



참고 : https://www.inflearn.com/course/ORM-JPA-Basic/dashboard 김영한 님의 JPA 프로그래밍 강의
https://book.naver.com/bookdb/book_detail.nhn?bid=9252528 자바 ORM 표준 JPA 프로그래밍
위의 책을 참고하고, 강의를 수강하면서 작성한 글입니다.
틀린 부분 등 다양한 피드백 환영합니다.

profile
열심히 성장 중 :)

0개의 댓글