자바 ORM 표준 JPA 프로그래밍 - 기본편
이 글은 김영한의 자바 ORM 표준 JPA 프로그래밍을 보고 작성한 글임을 알려드립니다.
관련 강의 : 인프런스 자바 ORM 표준 JPA 프로그래밍 - 기본편
데이터베이스 테이블의 연관관계를 설계하는 방법은
- 조인 컬럼 사용(외부 키 사용)
- 조인 테이블 사용(테이블 사용)
이렇게 크게 두 가지가 있다.
1) 조인 컬럼 사용
테이블 간에 관계는 주로 조인 컬럼이라 부르는 외래 키 컬럼을 사용해서 관리한다.
회원과 사물함이 있는데 각각 테이블에 데이터를 등록했다가 회원이 일할 때 사물함을 선택할 수 있다고 가정을 하면 회원이 사물함을 사용하기 전까지는 아직 둘 사이의 관계가 없으므로 Member 테이블의 외래 키에 null 값을 입력해 두어야 한다. 이처럼 외래 키에 null 값을 허용하는 관계를 선택적 비식별 관계라 한다.
선택적 비식별 관계는 외래키에 null값을 허용하므로 조인할 때 외부조인(Outer join)을 사용해야 한다.
2) 조인 테이블 사용
조인 테이블이라는 별도의 테이블을 사용해서 연관관계를 관리한다. 연관관게를 관리하는 조인 테이블을 추가하고 여기서 두 테이블의 외래 키를 가지고 연관관게를 관리하므로 Member와 Locker에는 연관관계를 관리하기 위한 외래 키 컬럼이 없다.
이 조인 테이블의 가장 큰 단점은 테이블을 하나 추가해야 한다는 것이며, 그로 인해 관리해야 하는 테이블이 늘어나고, 조인을 할 경우 조인 테이블까지 추가로 조인을 해야 한다.
그래서 평소에는 조인 컬럼을 사용해서 연관관계를 설계하고 필요에 따라 조인 테이블을 추가한다.
참고
- 조인 컬럼은 @JoinColumn으로 매핑한다.
- 조인 테이블은 @JoinTable로 매핑한다.
- 조인 테이블은 주로 다대다 관계를 일대다, 다대일 관계로 풀어내기 위해 사용하지만, 일대일, 일대다, 다대일 관계에서도 사용한다.
1. 일대일 조인 테이블
//부모
@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;
}
부모 엔티티에서 @JoinColumn이 아닌 @JoinTable을 사용하고 있다. 다음은 @JoinTable의 속성이다.
속성 | 기능 |
name | 매핑할 조인 테이블 이름 |
joinColumns | 현재 엔티티를 참조하는 외래 키 |
inverseJoinColumns | 반대방향 엔티티를 참조하는 외래 키 |
2. 일대다 조인 테이블
일대다 관계를 만들기 위해서는 다와 관련된 컬럼에 유니크 제약조건을 걸어야 한다.
//부모
@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<>();
}
//자식
@Entity
public class Child {
@Id
@GeneratedValue
@Column(name = "CHILD_ID")
private Long id;
private String name;
}
3. 다대일 조인 테이블
다대일은 일대다에서 방향만 반대이므로 일대다 조인 테이블과 모양이 같다.
//부모
@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<>();
}
//자식
@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;
}
이는 다대일, 일대다 양방향 관계로 매핑한 코드이다.
4. 다대다 조인 테이블
다대다 관계를 만들기 위해서는 두 테이블의 기본 키를 합해서 하나의 복합 유니크 제약 조건을 걸어야 한다.
//부모
@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<>();
}
//자식
@Entity
public class Child {
@Id
@GeneratedValue
@Column(name = "CHILD_ID")
private Long id;
private String name;
}
조인 테이블에 컬럼을 추가하면 @JoinTable 전략을 사용할 수 없다. 대신에 새로운 엔티티를 만들어서 조인 테이블과 매핑해야 한다.
5. 엔티티 하나에 여러 테이블 매핑
@Entity
@Data
@Table(name = "BOARD")
@SecondaryTable(name = "BOARD_DETAIL",
pkJoinColumns = @PrimaryKeyJoinColumn(name = "BOARD_DETAIL_ID"))
public class Board {
@Id
@GeneratedValue
@Column(name = "BOARD_ID")
private Long id;
private String title;
@Column(table = "BOARD_DETAIL")
private String content;
}
위의 코드처럼 @SecondaryTable을 사용하면 한 엔티티에 여러 테이블을 매핑할 수있다. 다음은 @SecondaryTable의 속성이다.
속성 | 기능 |
name | 매핑할 다른 테이블의 이름 |
pkJoinColumns | 매핑할 다른 테이블의 기본 키 컬럼 |
더 많은 테이블은 매핑하기 위해서는 @SecondaryTables를 사용하면 된다.
'STUDY > JPA' 카테고리의 다른 글
프록시와 연관관계 관리 #2 영속성 전이와 고아 객체 (0) | 2020.02.04 |
---|---|
프록시와 연관관계 관리 #1 프록시와 즉시로딩, 지연로딩 (0) | 2020.02.04 |
고급 매핑 #2 복합 키와 식별 관계 매핑 (0) | 2020.02.03 |
고급 매핑 #1 상속 관계 매핑, MappedSuperclass (0) | 2020.02.03 |
다양한 연관관계 매핑 (0) | 2020.01.30 |
댓글