@Entity
@Table(name="board")
public class Board implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int board_num;
private String title;
private String content;
private int member_num;
private Date reg_date;
// getter, setter
...
}
보통의 엔티티에는 PK인 컬럼 위에 @Id 어노테이션을 붙인다.
하지만 board_member에서처럼 복합키를 엔티티에 매핑하려면 어떻게 해야 할까?
@EmbeddedId
@Data
@Embeddable
class Board_member_id implements Serializable{
@Column(name = "board_num")
private int board_num;
@Column(name = "member_num")
private int member_num;
public Board_member_id(){}
public Board_member_id(int board_num, int member_num){
this.board_num = board_num;
this.member_num = member_num;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Board_member_id id = (Board_member_id) o;
return (board_num == id.board_num) && (member_num == id.member_num);
}
@Override
public int hashCode() {
return Objects.hash(board_num, member_num);
}
}
첫번째 방법은 Embeddable 어노테이션을 이용하는 것이다. Serializable 인터페이스를 구현한 클래스를 선언하고 복합키로 사용하는 컬럼을 필드로 만든다. 그리고 Serialiable을 상속해서 equals 및 hashCode 메서드를 구현해야 한다. 해당 메서드는 영속성 컨텍스트가 식별자를 비교할 때 사용하기 때문에 반드시 오버라이딩 해야한다. 뒤에 나오겠지만 IdClass와는 다르게 Embeddable 어노테이션을 이용하는 방법은 식별자 클래스에 기본 키를 직접 매핑해야 한다.
@Data
@Entity
class Board_member{
@EmbeddedId
private Board_member_id board_member_id;
}
엔티티 클래스 내부에 Embeddable 어노테이션을 이용하여 만든 클래스를 연관 관계로 설정하면 된다. 위 예제에서는 복합키를 제외한 다른 컬럼이 없지만 만약 있다면 Board_member 클래스의 필드로 들어가면 된다.
@IdClass
public class Board_member_id implements Serializable {
private int board_num;
private int member_num;
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Board_member_id id = (Board_member_id) o;
return (board_num == id.board_num) && (member_num == id.member_num);
}
@Override
public int hashCode() {
return Objects.hash(board_num, member_num);
}
//getter, setter
...
}
IdClass 어노테이션을 이용하는 방법은 식별자 클래스의 변수명과 엔티티에서 사용되는 변수명이 동일해야 하고, 마찬가지로 Serialiable을 상속해서 equals 및 hashCode 메서드를 구현해야 한다.
@Entity
@Table(name="board_member")
@IdClass(Board_member_id.class)
public class Board_member {
@Id
private int board_num;
@Id
private int member_num;
public Board_member() {}
public Board_member(Board_member_id id) {
this.board_num = id.getBoard_num();
this.member_num = id.getMember_num();
}
}
그리고 엔티티 클래스에는 @IdClass 어노테이션을 이용하여 식별자 클래스를 매핑해주고 식별자 클래스의 변수명과 동일한 이름의 변수를 선언해준다.
@EmbededId vs @IdClass
@EmbededId | @IdClass | |
장점 | - 객체지향적 | - 명시적으로 필드 노출 가능 - 식별 관계를 여러 테이블에서 사용할 때 연관 관계를 단순하게 유지 가능 |
단점 | - 복합키구조가 2개이상 테이블에 식별관계로 매핑될 때 복잡도 증가 | - 컬럼에 대한 필드 선언이 중복 발생 |
참고
'Spring' 카테고리의 다른 글
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) 에러 해결 (0) | 2024.02.18 |
---|---|
스프링에서 마이바티스(Mybatis) 사용하기 (0) | 2021.10.13 |
프로토타입 빈(Prototype Bean) (0) | 2021.10.09 |
JSON vs XML (0) | 2021.10.03 |
마이바티스(MyBatis) (0) | 2021.10.01 |
댓글