티스토리 뷰

JPA

JPA 복합키를 사용 하는 방법 2가지

MC's Father 2020. 10. 14. 21:25

대부분의 엔티티에는 @Id 애노테이션을 한 개 사용한다.

하지만 테이블의 키가 복합키로 이뤄져 있다면 엔티티를 설계할 때에 이를 고려해야 한다.

복합키 설정 방법은 두 가지가 있다. 

 

1.  @Embeddable 이용하는 방법

2.  @IdClass 이용하는 방법

첫 번째 방법이 객체지향 방식에 가깝다고 한다.

두 번째 방법은 DB 방식에 가깝다고 하는데 잘 와닿지는 않는다.

 

 

@Embeddable 이용 방법


다음과 같이 emp 테이블이 존재한다.

emp 테이블의 키는 emp_name, emp_no 두 개의 복합키로 이뤄져 있다.

create table emp (

    emp_name varchar(255) not null,

    emp_no integer not null,

    name varchar(255),

    primary key (emp_name, emp_no)

)

 

@EmbeddedId 를 이용하여 엔티티를 설계할 때에는 우선 Serializable 인터페이스를 구현한 클래스를 선언하고 필드에 복합키로 사용되는 컬럼을 선언하면 된다.

그리고 @Embeddable 애노테이션을 추가해 주자.

@Data

@Embeddable

class EmpId implements Serializable {



    @Column(name = "EMP_NO")

    private int empNo;



    @Column(name = "EMP_NAME")

    private String empName;

}

 

복합키에 대한 클래스를 생성했으니 이를 엔티티와 결합시켜야 한다.

방법은 간단하다.

Emp 엔티티 클래스 내부에 복합키를 위한 클래스인 EmpId를 객체 연관 관계로 설정하면 된다.

그리고 @EmbeddedId 애노테이션을 붙여주면 설정 끝

@Data

@Entity

class Emp {



    @EmbeddedId

    private EmpId empId;



    private String phone;

}

 

테스트를 해보자.

@Test

@Transactional

public void testEmbeddable() {

    EmpId empId = new EmpId();

    empId.setEmpNo(1);

    empId.setEmpName("nklee");



    Emp emp = new Emp();

    emp.setEmpId(empId);

    emp.setPhone("010-1111-1111");



    em.persist(emp);

    em.flush();

    em.clear();



    emp = em.find(Emp.class, empId);

    assertThat(1, is(emp.getEmpId().getEmpNo()));

    assertThat("nklee", is(emp.getEmpId().getEmpName()));

}

 

@IdClass 이용 방법

order_id, product_id 복합키를 가지는 order_product 테이블이 존재한다.

create table order_product (

    order_id integer not null,

    product_id integer not null,

    amount integer not null,

    primary key (order_id, product_id)

)

 

 

Serializable 인터페이스를 구현한 클래스를 선언하고 필드를 정의하자.

@Data

class OrderProductPK implements Serializable {

    private int orderId;

    private int productId;

}

 

위와 같이 정의한 후 엔티티 클래스에 @IdClass(OrderProductPK.class) 설정을 추가해 주면 된다.

유의해야 할 부분은 OrderProduct 엔티티의 식별자 orderId 필드 이름이 OrderProductPK의 orderId 필드 이름과 같아야 한다.

 

@Data

@Entity

@IdClass(OrderProductPK.class)

class OrderProduct {



    @Id

    @Column(name = "ORDER_ID")

    private int orderId;



    @Id

    @Column(name = "PRODUCT_ID")

    private int productId;



    private int amount;

}

 

테스트 해보자.

@Test

@Transactional

public void testIdClass() {

    OrderProduct orderProduct = new OrderProduct();

    orderProduct.setOrderId(1);

    orderProduct.setProductId(2);

    orderProduct.setAmount(1000);



    em.persist(orderProduct);

    em.flush();

    em.clear();



    OrderProductPK pk = new OrderProductPK();

    pk.setOrderId(1);

    pk.setProductId(2);



    orderProduct = em.find(OrderProduct.class, pk);

    assertThat(1, is(orderProduct.getOrderId()));

    assertThat(2, is(orderProduct.getProductId()));

    assertThat(1000, is(orderProduct.getAmount()));

}

 

출처 : lng1982.tistory.com/286

 

12. [JPA] 복합키

대부분의 엔티티에는 @Id 애노테이션을 한 개 사용한다. 하지만 테이블의 키가 복합키로 이뤄져 있다면 엔티티를 설계할 때에 이를 고려해야 한다. 복합키 설정 방법은 두 가지가 있다. 1 2 @Embedda

lng1982.tistory.com

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함