6. 다양한 연관관계 매핑 (다대다)

HotFried·2023년 9월 26일
0

다대다

  • @ManyToMany 어노테이션 이용
    - 실무에서 이용하지 않음
    - 관계형 DB는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없다.

위 그림처럼 연결 테이블을 추가해서 일대다, 다대일 관계로 풀어내야한다.
(객체는 컬렉션을 사용해서 객체 2개로 다대다 관계 가능)
@JoinTable 어노테이션으로 연결 테이블을 지정한다.


다대다 단방향

하나의 엔티티에만 @ManyToMany 어노테이션을 작성한다.

@Entity
public class Member {

    @ManyToMany
    @JoinTable(name = "MEMBER_PRODUCT")
    private List<Product> products = new ArrayList<>();
}

@Entity
public class Product {
    @Id
    @GeneratedValue
    private Long id;

    private String name;
}

다대다 양방향

일반적인 양방향 매핑과 유사하게, 반대쪽 엔티티에 mappedBy 어노테이션을 작성한다.

@ManyToMany(mappedBy = "products")
    private List<Member> members = new ArrayList<>();

한계

  • 편리해 보이지만 실무에서 사용 X

  • 연결 테이블이 단순히 연결만 하고 끝나지 않음
    주문시간, 수량 같은 추가적인 데이터가 필요해도 테이블에 데이터를 추가할 수 없다.

  • 예상치 못한 쿼리가 나갈 수 있다.
    중간 테이블이 숨겨져 있기 때문에 예상하지 못한 쿼리가 나가서 문제가 발생할 수 있다.


다대다 한계 극복

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

  • @ManyToMany -> @OneToMany, @ManyToOne

@Entity
public class Member {
  @Id @Column(name = "MEMBER_ID")
  private String id;

  @OneToMany(mappedBy = "product")
  private List<Order> orders;
}


@Entity // 연결 테이블용 엔티티(Order)
public class Order {
  @Id
  @ManyToOne
  @JoinColumn(name = "MEMBER_ID")
  private Member member;

  @Id
  @ManyToOne
  @JoinColumn(name = "PRODUCT_ID")
  private Product product;
}


@Entity
public class Product {
  @Id @Column(name = "PRODUCT_ID")
  private String id;

  @OneToMany(mappedBy = "product")
	private List<Member> members;
}
  • 중간 테이블연관 관계의 주인으로 둔다.

참고 :

김영한. 『자바 ORM 표준 JPA 프로그래밍』. 에이콘, 2015.

자바 ORM 표준 JPA 프로그래밍 - 기본편

profile
꾸준하게

0개의 댓글