반응형
Notice
Recent Posts
Recent Comments
관리 메뉴

간단한 개발관련 내용

6장 다양한 연관관계 매핑 본문

IT 책/JPA (ORM 표준 JPA 프로그래밍)

6장 다양한 연관관계 매핑

vincenzo.dev.82 2024. 11. 19. 13:44
반응형
  • 다중성
    • 다대일
      • 단방향, 양방향
    • 일대다
      • 단방향, 양방향
    • 일대일
      • 주 테이블 단방향, 양방향
      • 대상 테이블 단방향, 양방향
    • 다대다
      • 단방향, 양방향
  • 단방향, 양방향
  • 연관관계의 주인
    • 연관관계의 주인은 mappedBy 속성을 사용하지 않는다

 

6.1 다대일

6.1.1 다대일 단방향 [N:1]

6.1.2 다대일 양방향 [N:1, 1:N]

  • 양방향은 외래 키가 있는 쪽이 연관관계의 주인이다
  • 양방향 연관관계는 서로를 참조해야 한다

6.2 일대다

  • 일대다는 다대일의 반대로 Collection, List, Set, Map 중에 하나를 사용해야 한다

6.2.1 일대다 단방향 [1:N]

  • 한 팀이 여러 회원을 참조하는데 회원은 팀을 참조하지 않을 때
  • 일대다 단방향 관계를 매핑할 때는 @JoinColumn을 명시해야 한다. 그렇지 않으면 JPA는 연결 테이블을 중간에 두고 연관관계를 관리하는 조인 테이블 전략을 기본으로 사용해서 매핑한다
  • 일대다 단방향 매핑의 단점
    • 외래 키가 다른 테이블에 있으므로 연관관계 갱신을 위해 별도의 UPDATE 쿼리 실행이 필요하다
  • 일대다 단방향 매핑보다 다대일 양방향 매핑을 사용하자
    • 다대일 양방향 매핑은 관리해야 하는 외래 키가 본인 테이블에 있다. 따라서 일대다 단방향 매핑같은 문제가 발생하지 않는다. 상황에 따라 다르겠지만 일대다 단방향 매핑보다는 다대일 양방향 매핑을 권장한다.

6.2.2 일대다 양방향 [1:N, N:1]

  • 일대다이거나 다대일이거나 사실 같은 말이나 연관관계 주인을 어디로 두냐에 따라 차이
  • 일대다 양방향 매핑은 존재하지 않는다 대신 다대일 양방향 매핑을 사용
  • 연관관계 주인은 @ManyToOne을 사용한 곳이고 mappedBy는 @OneToMany에 있다
  • 될 수 있으면 다대일 매핑을 사용하되 다대일 단방향을 추가하게 되면 @JoinColumn에 insertable=false, updatable=false로 설정해서 읽기만 가능하게 하자

6.3 일대일 [1:1]

  • 일대일은 그 반대도 일대일
  • 일대일은 주테이블이나 대상테이블 둘 중 어느 곳이나 외래 키를 가질 수 있다
  • 주테이블에 외래키?
    • 주객체가 대상객체를 참조하는 것과 같은 형태
  • 대상테이블에 외래키?
    • 전통적인 방법이고 일대다로 변경 시 유리하다

6.3.1 주 테이블에 외래 키

  • Member가 주테이블 Locker가 대상테이블
  • 단방향
    • Member에 Locker에 대한 참조만 OneToOne
  • 양방향
    • Locker에 mappedBy로 member에 대한 참조 추가

6.3.2 대상 테이블에 외래 키

  • 대상테이블 Locker에 Member에 대한 키를 두게 되면, Member에 mappedBy 설정이 된다.
    • 외래 키가 Locker에 있으니까

6.4 다대다 [N:N]

  • 관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없다. 그래서 보통 다대다 관계를 일대다, 다대일 관계로 풀어내는 연결 테이블을 사용한다.
  • 그런데 객체는 테이블과 다르게 객체 2개로 다대다 관계를 만들 수 있다. @ManyToMany

6.4.1 다대다 : 단방향

  • Member_Product 라는 연결테이블은 @JoinTable에서만 쓰이고 객체로 만드는 신경을 쓰지 않아도 된다

6.4.2 다대다 : 양방향

  • Product 클래스에서는 mappedBy로 상품을 구매한 Lsit<Member>를 참조

6.4.3 다대다 : 매핑의 한계와 극복, 연결 엔터티 사용

  • @ManyToMany를 사용하면 연결 테이브을 자동을 처리해주므로 도메인 모델이 단순해지고 여러 가지로 편리하다. 하지만 이 매핑을 실무에서 사용하기에는 한계가 있다.
  • Member_Product 에 수량등의 필드가 추가되면 접근할 수 없기 때문에 결국 Member, Product와 일대다 다대일 관계를 만들어야 한다
  • MemberProduct 엔터티에 @IdClass를 사용하여 복합키 엔터티를 구현
  • 복합기본키
    • JPA에서 복합 키를 사용하려면 별도의 식별자 클래스를 만들어야 한다. @IdClass를 사용해서 식별자 클래스를 지정한다.
    • 복합 키는 별도의 식별자 클래스로 만들어야 한다.
    • Serializable을 구현해야 한다
    • equals와 hashcode 메소드를 구현해야 한다
    • 기본 생성자가 있어야 한다
    • 식별자 클래스는 public이어야 한다
    • @IdClass를 사용하는 법 외에 @EmbeddedId를 사용하는 방법도 있다
  • 식별관계
    • 회원상품은 회원과 상품의 기본 키를 받아서 자신의 기본 키로 사용한다. 이렇게 부모 테이블의 기본 키를 받아서 자신의 기본 키 + 외래 키로 사용하는 것을 데이터베이스 용어로 식별관계(Identifying Relationship)라 한다

6.4.4 다대다 : 새로운 기본 키 사용

  • MemberProduct 보다는 Order라는 이름으로 변경했다
  • Order에는 Member와 Product에 대한 @ManyToOne 관계가 설정되었다.

6.4.5 다대다 연관관계 정리

  • 다대다 관계를 일대다,다대일 관계로 풀어내기 위해 연결 테이블을 만들 때 식별자를 어떻게 구성할지 선택한다.
  • 식별관계 (복합키)
    • 받아온 식별자를 기본키 + 외래키로 사용한다.
    • 주문의 복합키로 회원과 상품의 키를 묶어서 사용하면 식별관계
  • 비식별관계
    • 받아온 식별자는 외래키로만 사용하고 새로운 식별자를 추가한다

6.5 정리

실전 예제 | 3. 다양한 연관관계 매핑

  • 주문과 배송
    • 주문과 배송은 일대일 관계다. 객체 관계를 고려할 때 주문에서 배송으로 자주 접근할 예정이므로 외래 키를 주문 테이블에 두었다. 참고로 일대일 관계이므로 ORDERS 테이블에 있는 DELIVERY_ID 외래 키에는 유니크 제약조건을 주는 것이 좋다.

페이지 요약


다양한 연관관계 매핑 개요

  • JPA에서는 다대일, 일대다, 일대일, 다대다 등 다양한 다중성의 연관관계를 매핑할 수 있다
  • 연관관계는 단방향과 양방향으로 구분되며, 양방향에서는 연관관계의 주인을 지정해야 한다

주요 연관관계 유형

  • 다대일 양방향 매핑이 가장 많이 사용되며, 외래 키가 있는 쪽이 연관관계의 주인이 된다
  • 일대다 단방향 매핑은 별도의 UPDATE 쿼리가 필요하므로 다대일 양방향 매핑을 권장한다
  • 일대일 관계에서는 주 테이블이나 대상 테이블 중 어느 곳에나 외래 키를 둘 수 있다

다대다 관계 처리

  • 객체는 컬렉션을 사용해 다대다 관계를 표현할 수 있지만, 실무에서는 중간 엔티티를 사용해 일대다, 다대일 관계로 풀어내는 것이 좋다
  • 다대다 관계를 풀어낼 때는 식별 관계(복합 키)나 비식별 관계(새로운 기본 키)를 선택할 수 있다
반응형