복합키 만드는 방법 2가지

0

JPA

목록 보기
12/15

첫번째 방법 @IdClass

  1. 복합키 클래스를 만든다.
@Getter @Setter // 필수
@EqualsAndHashCode // 필수
public class LinePK  implements Serializable{ // Serializable : 객체 직렬화 작업
	private static final long serialVersionUID = 1L;
	private Info info; // Line과 멤버변수를 2번 설정하는 것이기 때문에 객체지향 설계가 아니다. 하지만 @Id가 간단하게 쓸수있는방법임.
	private P lineP;
}
  1. 복합키를 만드려는 클래스에 @IdClass(복합키클래스이름.class) 어노테이션을 넣어준다.

두번째 방법 @Embedded class

  • 위에는 @IdClass(복합키클래스이름.class)를 사용할 때 복합키클래스고, 아래는 @Embedded 를 사용할 때 복합키 클래스임

공통점

  • LinePk도 LineEmbedded도 Serializable을 구현함
    @EqualsAndHashCode 도 둘다 붙여줌

차이점

  • LineEmbedded은 추가로 @Embeddable 어노테이션이 있다.
  • line_no와 line_pno에 연결할 것이면 @Column 없이 PK로 사용할 멤버변수만 선언해준다.
    • 부모 클래스가 갖고있는 멤버변수의 이름, 자료형과 LineEmbedded에서 설정한 자료형과 멤버변수의 이름과 같아야함 (주문(FK)에서 사용할 상품(PK)의 멤버변수)
  • 원래 클래스 PK에@Id없이 @MapsId를 붙여준다.
    • @MapsId("복합키클래스에서 설정한 멤버변수")
    • 복합키에서 선언한 멤버변수 중 어떤 멤버변수와 엮을 것인지 적어주면 됨
    • @Id로 설정하지 않으니, 복합키 클래스의 어떤것과 엮을지 알려주는 역할
    • P클래스가 갖고있는 멤버변수의 이름, 자료형과 LineEmbedded에서 설정한 자료형과 멤버변수의 이름과 같아야함

  • 기존 Line.class에서 다른 멤버변수들은 @Id 없이 @OneToMany@ManyToOne으로 설정한것만 가져오면 됨

@IdClass를 이용한 코드

@Entity
@IdClass(LinePK.class)  // pk가 복합키로 설정돼있을 경우 복합키용 PK 클래스를 따로 만들어서 가져와야함
@Table(name = "line_tbl")
public class Line { // 복합키 구성하기 위해서는 serializable 구현해야함 -> PK클래스에서 해주기때문에 빼도 됨
    @Id
    @ManyToOne
    @JoinColumn(name="line_no")  // info에서 fk역할을 할 변수
    private Info info; // info 타입을 가져가 info가 line을 fk로 가질 수 있는 것

    @Id
    @ManyToOne // line이 many입장
    @JoinColumn(name="line_pno")  // FK
    private P lineP;

    @Column(name="line_q")
    private int LineQ;

Embedded 클래스를 이용한 코드

@Entity
@Table(name = "line_tbl")
public class Line {
    @EmbeddedId
    private LineEmbedded id = new LineEmbedded(); // reflection 오류 떠서 객체 생성하는 부분 추가

    @MapsId("lineNo")
    @ManyToOne
    @JoinColumn(name="line_no")  // info에서 fk역할을 할 변수
    private Info info; // info 타입을 가져가 info가 line을 fk로 가질 수 있는 것

    @MapsId("pNo")
    @ManyToOne // line이 many입장
    @JoinColumn(name="line_pno")  // FK
    private P lineP;

    @Column(name="line_q")
    private int LineQ;
}
  • 뭐가 좋다 나쁘다는 아님.
  • Embedded가 좀 더 객체지향적인 방법

@EqualsAndHashCode

: 복합키 사용시 EqualsAndHashCode를 오버라이딩 하는 어노테이션 또는 메서드를 만들어야 한다.
-> 왜? key들 사이에서 중복되지 않도록 함 (중복되지 않으려면 hashcode의 반환값이 달라야하고 equals = false가 꼭 나와야 함)

  • sequence 전략을 사용하면 전략 내부에 hashcode equals를 관리하도록 구현이 돼있음. @GeneratedValue 를 이용하면 이미 내장돼있는 기능임
  • 그 키에 해당하는 @EqualsAndHashCode처럼 오버라이딩하기 위한 복합키용 클래스를 따로 도출할 필요가 없음 -> 복합키 클래스 사용안하고 기본클래스로 사용하면 된다.

  • 시퀀스전략을 사용하지 않으면 복합키 클래스를 사용해서 복합키 단위로 키가 구분될 수 있도록 해줘야 한다.
  • 시퀀스전략을 사용하면 우리가 만드는게 아니라 jpa 쪽에서 Persistent Context에서 사용할수있는 절대 중복되지 않는 키를 알아서 만들어줌
  • 그 키에 해당하는 내부의 list애들도 자동으로 만들어지게 하면 됨 -> 안쪽 클래스에 @id만 설정해주면 알아서 equals hashcode를 만들어준다.
    ➡︎ 시퀀스 전략을 사용하지 않을 경우에는 복합키를 사용할때 복합키용 클래스를 반드시 만들어야한다.
    ➡︎ 💡 시퀀스 전략을 사용하면 복합키클래스를 굳이 만들 필요가 없다.
profile
백엔드를 공부하고 있습니다.

0개의 댓글