JPA

[JPA] 11. 연관관계 매핑 - 다대다(N : M)

inuma 2021. 1. 11. 00:20
프로젝트 git url github.com/rtef23/JpaStudy
필요 1. docker
2. docker-compose
프로젝트 정보 mysql : 5.7 - docker image
java : 1.8

 

다대다(N : M)

  • @ManyToMany
  • 관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없음
    • > 중간 매핑 테이블을 추가해서 일대다, 다대일 관계로 풀어내야 함
  • 객체는 컬렉션을 사용하여 다대다 관계를 표현할 수 있음
  • @JoinTable로 연결 테이블을 지정

다대다 단방향 매핑

@Entity
@Table(name = "USER")
public class User {
  @Id
  @GeneratedValue
  @Column(name = "user_id")
  private Long id;

  @Column(name = "username")
  private String username;

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

@Entity
@Table(name = "PRODUCT")
public class Product {
  @Column(name = "name")
  private String name;

  ...
}

 

다대다 양방향 매핑

@Entity
@Table(name = "USER")
public class User {
  @Id
  @GeneratedValue
  @Column(name = "user_id")
  private Long id;

  @Column(name = "username")
  private String username;

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

@Entity
@Table(name = "PRODUCT")
public class Product {
  @Column(name = "name")
  private String name;

  @ManyToMany(mappedBy = "products")
  private List<User> users = new ArrayList<>();

  ...
}

 

  • 연결 테이블이 단순히 연결만 하는 경우가 없기 때문에 매핑 테이블용 엔티티를 추가하는 편이 좋다.
  • 중간 매핑 테이블에도 별도의 id를 주는 편이 확장성에 용이하다.

@Entity
@Table(name = "USER")
public class User {
  @Id
  @GeneratedValue
  @Column(name = "user_id")
  private Long id;

  @Column(name = "username")
  private String username;

  @OneToMany(mappedBy = "user")
  private List<UserProduct> userProducts = new ArrayList<>();
  
  ...
}

@Entity
@Table(name = "User_Product")
public class UserProduct {
  @Id @GeneratedValue private Long id;

  @ManyToOne
  @JoinColumn(name = "member_id")
  private User user;

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

@Entity
@Table(name = "PRODUCT")
public class Product {
  @Column(name = "name")
  private String name;

  @OneToMany(mappedBy = "product")
  private List<UserProduct> userProducts = new ArrayList<>();
  
  ...
}