개발자꿈나무
복합 키 매핑 본문
★ 복합 키 매핑
- 복합 키를 매핑하는 방법은 @IdClass를 이용하는 방법과 @EmbeddedId를 이용하는 방법 두 가지가 있다.
@IdClass는 좀 더 관계형 데이터베이스에 가까운 방법이고 @EmbeddedId는 좀 더 객체지향에 가까운 방법이다.
⭐︎ @IdClass 사용
@Entity
@IdClass(ParentId.class)
public class Parent {
@Id
private String id1;
@Id
private String id2;
private String name;
}
- 기본 키 컬럼 두 개를 @Id로 매핑하고, @IdClass를 사용해서 ParentId 클래스를 식별자 클래스로 지정했다.
public class ParentId implements Serializable {
private String id1;
private String id2;
public ParentId() {}
public ParentId(String id1, String id2) {
this.id1 = id1;
this.id2 = id2;
}
}
- 식별자 클래스는 몇 가지 조건을 만족해야 한다.
- 식별자 클래스의 속성명과 엔티티에서 사용하는 식별자의 속성명이 같아야 한다.
- Serializable 인터페이스를 구현해야 한다.
- 식별자 클래스는 public이어야 한다.
- 기본 생성자가 있어야 한다.
- 복합 키를 사용하는 엔티티를 저장하고 조회할 때는 이런 방법을 사용하면 된다.
//저장
Parent parent = new Parent();
parent.setId1("id1");
parent.setId2("id2");
parent.setName("hh");
em.persist(parent);
//조회
ParentId parentId = new ParentId("id1", "id2");
Parent parent1 = em.find(Parent.class, parentId);
parent1.getName(); //hh
- 저장 코드에는 ParentId의 모습이 보이지 않는데 em.persist를 호출하면 영속성 컨텍스트에 엔티티를 등록하기 직전에 내부에서 Parent.id1, Parent.id2 값을 사용해서 식별자 클래스인 ParentId를 생성하고 영속성 컨텍스트의 키로 사용한다.
@Entity
public class Child {
@Id
private String id;
@ManyToOne
@JoinColumns({
@JoinColumn(name = "PARENT_ID1"), @JoinColumn(name = "PARENT_ID2")
})
private Parent parent;
}
- 자식 테이블의 외래 키도 복합 키로 사용하고 있으므로 외래 키 매핑 시 여러 컬럼을 매핑해야 하므로 @JoinCoumns 어노테이션을 사용하고 각각의 외래 키 컬럼을 @JoinColumn으로 매핑한다.
- 부모 테이블의 PK 명과 자식 테이블의 FK 명이 같지 않을 때는 referencedColumnName 속성을 이용해서 이름을 설정해준다.
⭐︎ @EmbeddedId 사용
@Entity
public class Parent {
@EmbeddedId
private ParentId id;
private String name;
}
- @IdClass와 다르게 ParentId를 타입으로 가지는 id 필드를 선언해주고 @EmbeddedId 어노테이션을 적어주기만 하면 된다.
@Embeddable
public class ParentId implements Serializable {
@Column(name = "PARENT_ID1")
private String id1;
@Column(name = "PARENT_ID2")
private String id2;
public ParentId() {}
public ParentId(String id1, String id2) {
this.id1 = id1;
this.id2 = id2;
}
}
- 식별자 클래스에 기본 키를 직접 매핑하며, @EmbeddedId를 적용한 식별자 클래스도 몇 가지 조건을 만족해야 한다.
- @Embeddable 어노테이션을 붙여주어야 한다.
- Serializable 인터페이스를 구현해야 한다.
- 기본 생성자가 있어야 한다.
- 식별자 클래스는 public이어야 한다.
- 복합 키를 사용하는 엔티티를 저장하고 조회할 때는 이런 방법을 사용하면 된다.
//저장
Parent parent = new Parent();
ParentId parentId = new ParentId("id1", "id2");
parent.setId(parentId);
parent.setName("hh");
em.persist(parent);
//조회
ParentId findParentId = new ParentId("id1", "id2");
Parent parent1 = em.find(Parent.class, findParentId);
- @IdClass와 다른 점을 저장할 때 식별자 클래스 parentId를 직접 생성해서 사용한다는 점이다.
@EmbeddedId가 좀 더 객체 지향적이고 중복이 없어서 좋아보일 순 있으나, 특정 상황에서는 JPQL이 더 길어질 수 있으므로 @IdClass와 @EmbeddedId는 각각 장단점이 있으므로 취향껏 사용하면 된다.
em.creatQuery("select p.id.id1, p.id.id2 from Parent p"); //@EmbeddedId
em.creatQuery("select p.id1, p.id2 from Parent p"); //@IdClass
'자바 > JPA' 카테고리의 다른 글
프록시 (0) | 2023.08.22 |
---|---|
실전 예제 - 상속관계 매핑 (0) | 2023.08.21 |
@MappedSuperclass (0) | 2023.08.18 |
상속 관계 매핑 (0) | 2023.08.18 |
실전 예제 - 다양한 연관관계 매핑 (0) | 2023.08.17 |