JPA 연관관계 매핑의 종류
JPA 연관관계 매핑의 종류는 @ManyToOne, @OneToMany, @OneToOne, @ManyToMany가 있다.
이 글에서는 @ManyToMany 관계에 대해 다룬다.
@ManyToMany : 다대다 매핑
RDBMS는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없다.
따라서 연결 테이블을 추가해서 다대다 관계를 일대다 + 다대일 관계로 풀어내야 한다.
결론적으로는 다대다 매핑은 실무에서 사용하지 않는 방법이라고 한다.
@ManyToMany 양방향 매핑 example
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
private String username;
@ManyToMany
@JoinTable(name = "MEMBER_PRODUCT")
private List<Product> products = new ArrayList<>();
}
@Entity
public class Product {
@Id @GeneratedValue
private Long id;
private String name;
@ManyToMany(mappedBy = "products")
private List<Member> members = new ArrayList<>();
}
이렇게 매핑을 설정하면 JPA가 자동으로 연결 테이블(MEMBER_PRODUCT)을 만들어준다.
다대다 매핑의 한계
- JPA가 자동으로 연결 테이블을 생성하지만 해당 쿼리가 예측하기 어렵다.
- 비즈니스 로직을 위한 정보들이 해당 연결 테이블에 들어가야 하지만
JPA가 만든 연결테이블에는 다른 컬럼을 추가할 수 없다.
다대다 매핑의 한계 극복 방법
연결 테이블 용 엔티티를 추가한다.
예를 들어 Member(이용자)와 Product(상품) 사이에 MemberProduct라는 엔티티를 추가한다.
해당 MemberProduct 엔티티에서 Member와 Product를 FK로 가지며, 다른 부가 정보들을 추가할 수 있다.
연결 테이블 용 엔티티
@Entity
public class MemberProduct {
@Id @GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "MEMBER_ID")
private Member member;
@ManyToOne
@JoinColumn(name = "PRODUCT_ID")
private Product product;
private int amount;
private int price;
private LocalDateTime orderDateTime;
}
MemberProduct는 MEMBER_ID와 PRODUCT_ID를 FK로 가지게 되고, 각각 ManyToOne으로연관관계의 주인이 된다.
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
private String username;
@OneToMany(mappedBy = "member")
private List<MemberProduct> memberProducts = new ArrayList<>();
}
Member는 MemberProduct의 member와 매핑된다.
@Entity
public class Product {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "product")
private List<MemberProduct> memberProducts = new ArrayList<>();
}
Product는 MemberProduct의 product와 매핑된다.
이후에 이 MemberProduct의 이름을 비즈니스 상황에 맞게 변경하면 된다.
이 상황에서는 이용자가 상품을 주문한다면 MemberProduct를 Order로 변경하여 의미를 부여할 수 있다.
(참고) 인프런 - 김영한 님 '자바 ORM 표준 JPA 프로그래밍 - 기본 편'
https://www.inflearn.com/course/ORM-JPA-Basic
반응형
'Database > JPA' 카테고리의 다른 글
[JPA / Spring] JPQL을 이용해서 Entity가 아닌 DTO를 반환하는 방법 (0) | 2024.05.07 |
---|---|
[JPA] 연관관계 매핑 (1) | 2023.10.06 |
[JPA] 연관관계 매핑 - @OneToOne 일대일 매핑 (0) | 2023.10.06 |
[JPA] 연관관계 매핑 - @ManyToOne, @OneToMany (0) | 2023.10.06 |
[JPA] @Entity - 필드와 컬럼 매핑의 여러가지 속성 (1) | 2023.10.04 |