다대다 매핑 In JPA(분석)

Developer:Bird·2021년 1월 3일
0

목차

0.다대다 매핑이란?
1.다대다 매핑 In Jpa
👉 @ManyToMany
특징,사용방법,한계
👉 식별 관계
-@IdClass
-@EmbededId
👉 비식별 관계

✅ 0. 다대다 매핑이란


다음과같이 Member와 Product의 경우 Member 하나에 여러가지 Product를 가질 수 있고 Product의 경우도 여러 Member가 소유할수 있을때, 즉 N:M관계일때 '다대다 매핑' 이라고 하며 Join 테이블을 하나 더 만들어서 관리하는게 일반적인 관리방법이다.

1. 다대다 매핑 In Jpa

▶ @Many to Many

> 특징

  • 다음 그림과 같이 MEMBER_PRODUCT에서 오직 MEMBER와 PRODUCT로 부터 외래키만 속성으로 가질경우 사용가능하다.
  • 따로 Entity 클래스를 만들 필요가 없다.

> 사용방법 (위의 예제를 기반으로 작성하겠다)

  • 단방향: 연관관계의 주인에 해당하는 엔티티에만 다음과 같이 작성을 하면 된다.
@Entity
public class Member{
....
@ManyToMany
@JoinTable(name=MEMBER_PRODUCT)
@JoinColumns=@JoinColumn(name="member_id"),
inverseJoinColumns=@JoinColumn(name="product_id"))
private List<Product> products=new ArrayList<Product>();
  • 양방향: 연관관계의 주인에 해당하는 쪽과 영향받는쪽 두쪽다 설정해주면된다.
    주인의 경우는 이전과 같다.
    노예
@Entity
public class Product{
....
@ManyToMany(mappedBy "products")//역방향
private List<Member> members;

> 한계:

다음과 같이 MEMBER_PRODUCT 테이블에 MEMBER가 해당 PRODUCT를 몇개나 가지고 있는지 알기위한 'PRODUCT_COUNT'라는 속성을 추가하고 싶어도 추가하지 못한다.

식별관계(복합키 사용)

식별 관계란? Join테이블에 기본키를 외래키들로 설정하는법

다음의 경우를 보면 알다시피 외래키를 제외한 자신만의 기본키는 존재하지 않는다.

▶ @IdClass

@Data
public class MemberProductId implements Serializable{

  private String member;
  private String product;
  //hash and equals...
}

@Entity
@Data
@IdClass(MemberProductId.class)
public class PRODUCT_MEMBER {

  @Id
  @ManyToOne
  @JoinColumn(name = "member_id")
  private Member member;

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

  private int productCount;
}

특징
복합키는 별도의 식별자 클래스로 만들어야한다.
Serializable을 구현
equals와 hashcode메서드 구현(자동완성기능)
식별자 클래스는 Public이다.

▶ @EmbededId


@Embeddable
@Data
public class CompositeKey implements Serializable {
    @Column(name = "product_id")
    private Long categoryId;
    @Column(name = "item_id")
    private Long itemId;
    
    hash and equals..
}
@Entity
@Getter
@Setter
public class MemberProduct {

   @EmbeddedId
   private CompositeKey id=new CompositeKey();

   @ManyToOne
   @MapsId("product_id")
   @JoinColumn(name = "member_id")
   private Member category;

    @ManyToOne
    @MapsId("item_Id")
    @JoinColumn(name = "product_id")
    private Product item;

    private int orderAmount;

}

특징:IDClass의 경우와 유사한점이 많다.
다만 조금더 객체지향적인 방법이다.

profile
끈임없이 발전하자.

1개의 댓글

comment-user-thumbnail
2021년 10월 29일

저렇게 설계된 경우에 컨트롤러나 서비스에서는 어떤식으로 코드를 짜야하나요? 해당 코드를 참고해서 db에 save작업을 하려고하는데 계속 NPE가 뜨네요.. ㅠㅠ

답글 달기