Spring/jpa

[JPA] 조인 테이블

라임온조 2023. 2. 21. 09:45

1. 데이터베이스 테이블의 연관관계를 설계하는 방법

1) 조인 컬럼 사용(외래키)

MEMBER LOCKER
MEMBER_ID(PK) LOCKER_ID(PK)
USERNAME NAME
LOCKER_ID(FK, NULL 허용)  

특징

  • 외래 키에 null을 허용하는 선택적 비식별 관계
  • 회원과 사물함을 조인할 때 외부 조인을 사용해야 한다. 내부 조인을 사용하면 사물함과 관계가 없는 회원은 조회되지 않는다.
  • 회원과 사물함이 아주 가끔 관계를 맺는다면 외래 키 값 대부분이 null로 저장되는 단점이 있다.

2) 조인 테이블 사용(테이블 사용)

MEMBER MEMBER_LOCKER LOCKER
MEMBER_ID(PK) MEMBER_ID(FK) LOCKER_ID(PK)
USERNAME LOCKER_ID(FK) NAME

특징

  • 조인 테이블이라는 별도의 테이블에 다른 두 테이블의 외래 키를 가지고 연관관계를 관리
  • 테이블을 하나 추가해야 하고, 회원과 사물함 두 테이블을 조인하려면 MEMBER_LOCKER 테이블까지 추가로 조인해야 한다는 단점이 있다.

2. 일대일 조인 테이블

특징

  • 조인 테이블의 외래 키 컬럼 각각에 총 2개의 유니크 제약 조건을 걸어야 한다
PARENT PARENT_CHILD CHILD
PARENT_ID(PK) PARENT_ID(PK, FK) CHILD_ID(PK)
NAME CHILD_ID(UNI, FK) NAME
@Entity
public class Parent{
	
    @Id
    @GeneratedValue
    @Column(name = "parent_id")
    private Long id;
    private String name;
    
    @OneToOne
    @JoinTable(name = "parent_child", joinColumns = @JoinColumn(name = "parent_id"), inverseJoinColumns = @JoinColumn(name = "child_id"))
    private Child child;
    
}
@Entity
public class Child{
	@Id
    @GeneratedValue
    @Column(name = "child_id")
    private Long id;
    private String name;
}

3. 일대다 조인 테이블

특징

  • 조인 테이블의 컬럼 중 다와 관련된 컬럼에 유니크 제약조건을 걸어야 한다.
PARENT PARENT_CHILD CHILD
PARENT_ID(PK) CHILD_ID(PK, FK) CHILD_ID(PK)
NAME PARENT_ID(FK) NAME
@Entity
public class Parent{
	
    @Id
    @GeneratedValue
    @Column(name = "parent_id")
    private Long id;
    private String name;
    
    @OneToMany
    @JoinTable(name = "parent_child", joinColumns = @JoinColumn(name = "parent_id"), inverseJoinColumns = @JoinColumn(name = "child_id"))
    private List<Child> child = new ArrayList<Child>();
}
@Entity
public class Child{
	@Id
    @GeneratedValue
    @Column(name = "child_id")
    private Long id;
    private String name;
}

4. 다대일 조인 테이블

특징

  • 다대일은 일대다에서 방향만 반대이므로 조인 테이블 모양은 일대다에서 설명한 것과 같다
@Entity
public class Parent{
	@Id
    @GeneratedValue
    @Column(name = "parent_id")
    private Long id;
    private String name;
    
    @OneToMany(mappedBy = "parent")
    private List<Child> child = new ArrayList<Child>();
}
@Entity
public class Child{
	@Id
    @GeneratedValue
    @Column(name = "child_id")
    private Long id;
    private String name;
    
    @ManyToOne(optional = false)
    @JoinTable(name = "parent_child", joinColumns = @JoinColumn(name = "child_id"), inverseJoinColumns = @JoinColumn(name = "parent_id"))
    private Parent parent;
}

5. 다대다 조인 테이블

특징

  • 다대다 관계를 만들려면 조인 테이블의 두 컬럼을 합해서 하나의 복합 유니크 제약조건을 걸어야 한다
  • 조인 테이블에 컬럼을 추가하면 @JoinTable 전략을 사용할 수 없다. 대신에 새로운 엔티티를 만들어서 조인 테이블과 매핑해야 한다.
PARENT PARENT_CHILD CHILD
PARENT_ID(PK) PARENT_ID(PK, FK) CHILD_ID(PK)
NAME CHILD_ID(PK, FK) NAME
@Entity
public class Parent{
	@Id
    @GeneratedValue
    @Column(name = "parent_id")
    private Long id;
    private String name;
    
    @ManyToMany
    @JoinTable(name = "parent_child", joinColumns = @JoinColumn(name = "parent_id"), inverseJoinColumns = @JoinColumn(name = "child_id"))
    private List<Child> child = new ArrayList<Child>();
}
@Entity
public class Child{
	@Id
    @GeneratedValue
    @Column(name = "child_id")
    private Long id;
    private String name;
}