개발자꿈나무

복합 키 매핑 본문

자바/JPA

복합 키 매핑

망재이 2023. 8. 20. 20:57

★ 복합 키 매핑

- 복합 키를 매핑하는 방법은 @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
728x90

'자바 > JPA' 카테고리의 다른 글

프록시  (0) 2023.08.22
실전 예제 - 상속관계 매핑  (0) 2023.08.21
@MappedSuperclass  (0) 2023.08.18
상속 관계 매핑  (0) 2023.08.18
실전 예제 - 다양한 연관관계 매핑  (0) 2023.08.17