package com.example.jpa_project.ch06Example;
import lombok.Data;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Data
public class Member {
@Id
@GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String username;
@OneToOne
@JoinColumn(name = "LOCKER_ID")
private Locker locker;
@ManyToOne
@JoinColumn(name = "TEAM_ID", insertable = false, updatable = false)
private Team team;
@ManyToMany
@JoinTable(
name = "MEMBER_PRODUCT",
joinColumns = @JoinColumn(name = "MEMBER_ID"),
inverseJoinColumns = @JoinColumn(name = "PRODUCT_ID")
)
private List<Product> products = new ArrayList<>();
}
음.. 뭔가 많아 졌네...
Memeber 엔티티와 Product 엔티티를 매핑했는데, 방식으로는 @ManyToMany와 @JoinTable을 사용해서 진행했다. 이런 방식을 사용하게 되면 따로 Member_Product엔티티가 없어도 매핑을 할 수 있다는 점!
@JoinTable의 속성
name : 연결 테이블을 지정한다.
위의 같은 경우에는 Member측에서는 MemberId를, Product측에서는 ProductId를 내새웠기 때문에 Member_Product 엔티티의 구성은 위의 2 키를 PK, FK로 들고 있는 상황이 된다.
joinColumns : 현재 방향인 Member와 매핑할 조인 컬럼을 적어줌
inverseColumns : 반대 방향인 Product와 매핑할 조인 컬럼을 적어줌
신기하게도 이렇게 엔티티를 구성하고 저장하는 과정에서 product와 member를 세팅하고 persist를 통해 저장을 해준다면 신기하게도 연결 테이블에도 값이 저장된다.
조회할때도 자동으로 Member_Product테이블을 통해서 조회를 해준다..! 완전편리
다대다 양방향
기존에 일대일 단방향에서 양방향으로 바뀔때랑 같이 Product에도 Member에 대한(주인)에 대한 정보를 입력해주면 된다 → mappedBy가 없는 곳이 주인이다!!
Member
package com.example.jpa_project.ch06Example;
import lombok.Data;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Data
public class Member {
@Id
@GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String username;
@OneToOne
@JoinColumn(name = "LOCKER_ID")
private Locker locker;
@ManyToOne
@JoinColumn(name = "TEAM_ID", insertable = false, updatable = false)
private Team team;
@ManyToMany
@JoinTable(
name = "MEMBER_PRODUCT",
joinColumns = @JoinColumn(name = "MEMBER_ID"),
inverseJoinColumns = @JoinColumn(name = "PRODUCT_ID")
)
private List<Product> products = new ArrayList<>();
}
Product
package com.example.jpa_project.ch06Example;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import java.util.ArrayList;
import java.util.List;
@Entity
@Data
public class Product {
@Id
@GeneratedValue
private String Id;
private String name;
@ManyToMany(mappedBy = "products")
private List<Member> members = new ArrayList<>();
}
기본적인 ManyToMany 관계는 이러하다.
다대다의 한계점, 해결방안
이렇게만 되면 정말 행복하겠지만
한계점이 있다... 위와 같은 예시에서 Member와 Product의 매핑 사이에 날짜와 같은 새로운 컬럼이 추가되야 하는 경우가 있는데, 새로운 컬럼이 추가되게 되면 @ManyToMany로는 다대다 관계를 표현할 수 없고, 연결 엔티티를 따로 만들고 그 컬럼들에 기존의 매핑해야할 두 컬럼을 매핑해서 일대다, 다대일 관계로 풀어내야 한다..!
이번에는 그 연결 엔티티를 MemberProduct로 풀어내고자 한다.
그럼 일단 기존의 ManyToMany를 OneToMany, ManyToOne으로 해체를 시켜줘야한다.
일단 Member와 MemberProduct는 양방향 관계로 만들었고, 외래 키는 MemberProduct에서 가지고 있기 때문에 주 객체는 MemberProduct가 되고 Member에는 mappedBy로 주가 아님을 표현
Member
package com.example.jpa_project.ch06Example;
import lombok.Data;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Data
public class Member {
@Id
@GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String username;
@OneToMany(mappedBy = "member")
private List<MemberProduct> memberProducts;
}