-
1. 상속 관계 매핑
1) 조인 전략
- 엔티티 각각을 모두 테이블로 만들고 자식 테이블이 부모 테이블의 기본키를 받아서 기본키+외래키 로 사용한다.
- 데이터베이스 조회할 때에는 조인을 자주 사용한다.
- 객체는 타입으로 구분할 수 있지만 테이블은 타입의 개념이 없다.
- 타입을 구분하는 컬럼(DTYPE)의 추가가 필요하다.
JOIN 전략 @Entity @Inheritance(strategy = InheritanceType.JOINED) @DiscriminatorColumn(name = "DTYPE") public abstract class Item { @Id @GeneratedValue @Column(name = "ITEM_ID") private Long id; private String name; .... } @Entity @discriminatorValue("A") public class Album extends Item { private String artist; ... } @Entity @DiscriminatorValue("M") public class Movie extends Item { private String director; private String actor; .... }
- @Inheritance(strategy = InheritanceType.JOINED) : 상속 매핑은 부모 클래스에 @Inheritance 를 사용해야 한다.
매팽 전략을 지정해야 하는데 JOINED 를 사용했다.
- @DiscriminatorColumn(name="DTYPE") : 부모 클래스에 구분 컬럼을 지정한다. 기본 값이 DTYPE 이므로
@DiscriminatorColumn 으로 줄여서 사용해도 된다.
- @DiscriminatorValue("M") : 엔티티를 저장할 때 구분 컬럼(DTYPE)에 입력할 값을 지정한다.
//재정의 : 자식 테이블의 기본 키 컬럼명을 변경하고 싶을때 사용 @Entity @DiscriminatorValue("B") @PrimaryKeyJoinColumn(name="BOOK_ID") //ID 재정의 public class Book extends Item { private String author; private String isbn; }
- BOOK 테이블의 ITEM_ID 기본 키 컬럼명을 BOOK_ID로 변경했다.(재정의)
- 조인 전략의 장점 : 테이블이 정규화된다, 외래 키 참조 무결성 제약조건을 활용할 수 있다, 저장 공간이 효율적이다.
- 조인 전략의 단점 : 조회할 때 조인이 많이 사용되므로 성능이 저하될 수 있다, 쿼리가 복잡하다, 데이터를 등록할 때
INSERT SQL을 두번 실행한다.
- JPA 표준 명세는 구분 컬럼을 사용하도록 하지만, 하이버네이트를 포함한 몇몇 구현체는 구분 컬럼
(@discriminatorColumn) 없이도 동작한다.
- 관련 어노테이션 : @PrimaryKeyJoinColumn, @DiscriminatorColumn, @DiscriminatorValue
2) 단일 테이블 전략
- 테이블 하나만 사용한다.
- 구분 컬럼(DTYPE)으로 어떤 자식데이터가 저장되었는지 구분한다.
- 조회할 때 조인을 사용하지 않으므로 일반적으로 가장 빠르다.
단일 테이블 전략 - 자식 엔티티가 매핑한 컬럼은 모두 null을 허용해야 한다. (Book 엔티티를 쓰면 다른 컬럼은 null로 들어가기 때문)
@Entity @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="DTYPE") public abstract class Item { @Id @GeneratedValue @Column(name="ITEM_ID") private Long id; private String name; private int price; ... } @Entity @DiscriminatorValue("A") public class Album extends Item { ... } @Entity @DiscriminatorValue("M") public class Movie extends Item { ... } @Entity @DiscriminatorValue("B") public class Book extends Item { ... }
- 테이블 하나에 모든 것을 통합하므로 구분 컬럼을 필수로 사용해야 한다.
- 장점 : 조인이 필요 없어 빠르다, 조회 쿼리가 단순하다.
- 단점 : 자식 엔티티가 매핑한 컬럼은 모두 null을 허용해야 한다, 테이블이 커질 수 있어 상황에 따라 느려질 수 있다.
- 구분 컬럼을 꼭 사용해야 한다. 따라서 @DiscriminatorColumn 을 꼭 설정해야 한다.
- @DiscriminatorValue를 지정하지 않으면 기본으로 엔티티 이름을 사용한다. (Album, Movie, Book)
3) 구현 클래스마다 테이블 전략
- 자식 엔티티 마다 테이블을 만들고, 각 테이블에 필요한 컬럼이 모두 있다.
구현 클래스마다 테이블 전략 @Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) public abstract class Item { @Id @GeneratedValue @Column(name = "ITEM_ID") private Long id; private String name; private int price; ... } @Entity public class Album extends Item { ... } @Entity public class Movie extends Item { ... } @Entity public class Book extends Item { ... }
- 장점 : 서브 타입을 구분해서 처리할 때 효과적이다, not null 제약조건을 사용할 수 있다.
- 단점 : 여러 자식테이블을 함께 조회할 때 성능이 느리다(SQL에 UNION을 사용해야 한다).
- 구분 컬럼을 사용하지 않는다.
- 이 전략은 데이터베이스 설계자와 ORM 전문가 둘 다 추천하지 않는 전략이다.
2) @MappedSuperclass
1) @MappedSuperclass
- 부모 클래스를 테이블과 매핑하지 않고 상속받는 자식클래스에게 매핑정보만 제공하고 싶으면
@MappedSuperclass 를 사용한다.
- 단순히 맵핑정보를 상속할 목적으로만 사용한다.
- 회원과 판매자는 서로 관계가 없는 테이블과 엔티티이다.
- id, name 두 공통 속성을 부모 클래스로 모으고 객체 상속관계로 만든다.
@MappedSuperclass public abstract class BaseEntity { @Id @GeneratedValue private Long id; private String name; ... } @Entity public class Member extends BaseEntity { private String email; ... } @Entity public class Seller extends BaseEntity { private String shopName; ... }
- BaseEntity에는 객체들이 주로 사용하는 공통 매핑 정보를 정의했다.
- 자식 엔티티들은 상속을 통해 BaseEntity의 매핑 정보를 물려받았다.
- BaseEntity는 테이블과 매핑하지 않고, 자식 엔티티에게 공통으로 사용되는 매핑 정보만 제공한다.
- 부모로부터 물려받은 매핑 정보를 재정의하려면 @AttributeOverrides나 @AttributeOverride 를 사용하고,
연관관계를 재정의하려면 @AssociationOverrides나 @AssociationOverride를 사용한다.
@Entity @AttributeOverride(name="id", column=@Column(name="MEMBER_ID")) public class Member extends BaseEntity {...}
- 부모에게 상속받은 id 속성의 컬럼명을 MEMBER_ID로 재정의했다. 둘 이상을 재정의 하려면 아래와 같다.
@Entity @AttributeOverrides({ @AttributeOverride(name="id", column=@Column(name="MEMBER_ID")), @AttributeOverride(name="name", column=@Column(name="MEMBER_NAME")) }) public class Member extends BaseEntity { ... }
- @MappedSuperclass는 테이블과 매핑되지 않고 자식 클래스에 엔티티의 매핑 정보를 상속하기 위해 사용한다.
- @MappedSuperclass로 지정한 클래스는 엔티티가 아니므로 em.find()나 JPQL에 사용할 수 없다.
- 이 클래스를 직접 생성해서 사용할 일은 거의 없으므로 추상 클래스로 만드는 것을 권장한다.
- 엔티티(@Entity)는 엔티티(@Entity)이거나 @MappedSuperclass로 지정한 클래스만 상속받을 수 있다.
3. 복합 키와 식별 관계 매핑
1) 식별관계 vs 비식별 관계
- 식별관계 : 부모 테이블의 기본 키를 내려받아서 자식 테이블의 기본키+외래키 로 사용하는 관계이다.
- 비식별관계 : 부모 테이블의 기본 키를 받아서 자식 테이블의 외래키로만 사용하는 관계이다. 필수적 비식별 관계 와
선택적 비식별 관계로 나뉜다.
- 필수적 비식별 관계 : 외래키에 NULL을 허용하지 않는다. 연관관계를 필수적으로 맺어야 한다.
- 선택적 비식별 관계 : 외래 키에 NULL을 허용한다. 연관관계를 맺을지 말지 선택할 수 있다.
2) 복합 키: 비식별 관계 매핑
- 둘 이상의 컬럼으로 구성된 복합 기본 키는 별도의 식별자 클래스를 만들어야 한다.
- JPA는 영속성 컨텍스트에 엔티티를 보관할 때 식별자를 키로 사용한다. 그리고 식별자를 구분하기 위해 equals 와
hashCode 를 사용해서 동등성 비교를 한다.
- 식별자 필드가 하나일 때는 보통 자바의 기본 타입을 사용하므로 문제가 없지만, 2개 이상이면 식별자 클래스를
만들고 equals 와 hashCode 를 구현해야 한다.
- JPA는 복합 키를 지원하기 위해 @IdClass와 @EmbededId 2가지 방법을 제공하는데, @IdClass는 관계형 데이터
베이스에 가까운 방법이고 @EmbededId는 좀 더 객체 지향에 가까운 방법이다.
3) @IdClass (복합 키: 비식별관계)
- 복합 키 테이블은 비식별 관계고, PARENT는 복합 기본 키를 사용한다.
@Entity @IdClass(ParentId.class) public class Parent { @Id @Column(name="PARENT_ID1") private String id1; @Id @Column(name="PARENT_ID2") private String id2; private String name; ... } //식별자 클래스 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; } @Override public boolean equals(Object o) { ... } @Oberride public boolean hashCode() {...} }
- @IdClass를 사용할 때 식별자 클래스는 다음 조건을 만족해야 한다.
- 식별자 클래스의 속성명과 엔티티에서 사용하는 식별자의 속성명이 같아야 한다.
- Serializable 인터페이스를 구현해야 한다.
- equals, hashCode 인터페이스를 구현해야 한다.
- 기본 생성자가 있어야 한다.
- 식별자 클래스는 public이어야 한다.
// 복합키를 사용하는 엔티티 저장 Parent parent = new Parent(); parent.setId1("myId1"); parent.setId2("myId2"); parent.setName("parentName"); em.persist(parent);
- em.persist()를 호출하면 영속석 컨텍스트에 엔티티를 등록하기 직전에 내부에서 Parent.id1, Parent.id2 값을 사용해
서 식별자 클래스인 ParentId를 생성하고 영속성 컨텍스트의 키로 사용한다.
// 복합키를 사용한 조회 ParentId parentId = new ParentId("myId1","myId2"); Parent parent = em.find(Parent.class, parentId);
// 자식 클래스 (상속 관계 아님) @Entity public class Child { @Id private String id; @ManyToOne @JoinColumns({ @JoinColumn(name="PARENT_ID1", referencedColumnName="PARENT_ID1"), @JoinColumn(name="PARENT_ID2", referencedColumnName="PARENT_ID2") }) private Parent parent; ... }
- 부모 테이블의 기본 키 컬럼이 복합 키 이므로 자식 테이블의 외래 키도 복합 키다.
- 외래 키 매핑 시 여러 컬럼을 매핑해야 하므로 @JoinColumns 어노테이션을 사용하고 각각을 @JoinColumn 으로
매핑한다.
- @JoinColumn의 name 속성과 referencedColumnName 속성의 값이 같으면 referencedColumnName은 생략해도
된다.
4) @EmbeddedId (복합키: 비식별관계)
- @IdClass가 데이터베이스에 맞춘 방법이라면 @EmbededdId는 좀 더 객체지향적인 방법이다.
@Entity public class Parent { @EmbeddedId private ParentId id; private String name; ... } //식별자 클래스 @Embeddable public class ParentId implements Serializable { @Column(name="PARENT_ID1") private String id1; @Column(name="PARENT_ID2") private String id2; //equals and hashCode 구현 ... }
- @EmbeddedId를 적용한 식별자 클래스는 식별자 클래스에 기본키를 직접 매핑한다.
- 식별자 클래스는 다음을 만족해야 한다.
- @Embeddable 어노테이션을 붙여주어야 한다.
- Serializable 인터페이스를 구현해야 한다.
- equals, hashCode를 구현해야 한다.
- 기본 생성자가 있어야 한다.
- 식별자 클래스는 public 이어야 한다.
// 엔티티 저장 Parent parent = new Parent(); ParentId parentId = new ParentId("myId1", "myId2"); parent.setId(parentId); parent.setName("parentName"); em.persist(parent); //엔티티 조회 ParentId parentId = new ParentId("myId1","myId2"); Parent parent = em.find(Parent.class, parentId);
5) 복합키와 equals(), hashCode()
- 영속성 컨텍스트는 엔티티의 식별자를 키로 사용해서 엔티티를 관리하며, 식별자를 비교할때 equals() 와
hashCode() 를 사용한다.
- 복합 키는 equals() 와 hashCode()를 필수로 구현해야 한다. (자바의 기본은 인스턴스 참조 값 비교인 == 를
사용하는데, 이것은 복합키의 동일성을 판단하는데 맞지 않는다. )
6) @IdClass vs @EmbeddedId
- @EmbeddedId 가 @IdClass와 비교해서 더 객체지향 적이고 중복도 없긴 하지만 특정상황에 JPQL이 조금 더 길어
질 수 있다.
- 복합 키에는 @GeneratedValue 를 사용할 수 없다. 여러 컬럼중 하나에도 사용할 수 없다.
em.createQuery("select p.id.id1, p.id.id2 from Parent p"); //@EmbeddedId em.createQuery("select p.id1, p.id2 from Parent p"); //@IdClass
7) 복합 키: 식별 관계 매핑
- 부모, 자식, 손자까지 계속 기본 키를 전달하는 식별관계이다. (@IdClass 또는 @EmbeddedId 사용하여 매핑)
- @IdClass로 식별 할 경우는 다음과 같다.
//부모 @Entity Public class Parent{ @Id Column(name="PARENT_ID") private String id; private String name; ... } //자식 @Entity @IdClass(ChildId.class) public class Child{ @Id @ManyToOne @JoinColumn(name="PARENT_ID") public Parent parent; @Id @Column(name="CHILD_ID") private String childId; .... } //자식 Id public class ChildId implements Serializable { private String parent; //Child.parent 매핑 private String childId; //Child.childId 매핑 //equals, hashCode ... } //손자 @Entity @IdClass(GrandChildId.class) public class GrandChild{ @Id @ManyToOne @JoinColumns({ @JoinColumn(name="PARENT_ID"), @JoinColumn(name="CHILD_ID) }) private Child child; @Id @Column(name="GRANDCHILD_ID") private String id; ... } //손자 ID public class GrandChildId implements Serializable{ private ChildId child; //GrandChild.child 매핑 private String id; //GrandChild.id 매핑 //equals, hashCode ... }
- 식별 관계는 기본 키와 외래 키를 같이 매핑해야 한다. 따라서 @Id 와 @ManyToOne을 같이 사용한다.
- Child 엔티티의 parent 필드를 보면 @Id로 기본 키를 매핑하면서 @ManyToOne과 @JoinColumn 으로 외래 키를
같이 매핑한다.
- @EmbeddedId와 식별관계는 다음과 같다.
//부모 @Entity public class Parent{ @Id @Column(name="PARENT_ID") private String id; ... } //자식 @Entity public class Child{ @EmbeddedId private ChildId id; @MapsId("parentId") //ChildId.parentId 매핑 @ManyToOne @JoinColumn(name="PARENT_ID") public Parent parent; .... } //자식 ID @Embeddable public class ChildId implements Serializable{ private String parentId; //@MapsId("parentId")로 매핑 @Column(name="CHILD_ID") private String id; //equals, hashCode ... } //손자 @Entity public class GrandChild { @EmbeddedId private GrandChildId id; @MapsId("childId") //GrandChildId.childId 매핑 @ManyToOne @JoinColumns({ @JoinColumn(name="PARENT_ID"), @JoinColumn(name="CHILD_ID") }) private Child child; .... } //손자 ID @Embeddable public class GrandChildId implements Serializable{ private ChildId childId; //@MapsId("childId")로 매핑 @Column(name="GRAND_CHILD_ID) private String id; //equals, hashCode .... }
- @EmbeddedId는 식별 관례로 사용할 연관관계의 속성에 @MapsId를 사용하면 된다.
- @MapsId의 속성 값은 @EmbeddedId를 사용한 식별자 클래스의 기본 키 필드를 지정하면 된다.
8) 비식별 관계로 구현
//부모 @Entity public class Parent{ @Id @GeneratedValue @Column(name="PARENT_ID") private Long id; ... } //자식 @Entity public class Child{ @Id @GeneratedValue @Column(name="CHILD_ID") private Long id; @ManyToOne @JoinColumn(name="PARENT_ID") public Parent parent; .... } //손자 @Entity public class GrandChild { @Id @GeneratedValue @Column(name="GRANDCHILD_ID") private Long id; @ManyToOne @JoinColumn(name="CHILD_ID") private Child child; .... }
- 식별 관계보다 매핑도 쉽고 코드도 단순하다. 복합키 클래스를 만들지 않아도 된다.
9) 일대일 식별관계
- 일대일 식별 관계는 부모 테이블의 기본키 값만 사용한다.
- 부모 테이블의 기본 키가 복합 키가 아니면 자식 테이블의 기본 키는 복합 키로 구상하지 않아도 된다.
//부모 @Entity public class Board{ @Id @GeneratedValue @Column(name="BOARD_ID") private Long id; @OneToOne(mappedBy="board") private BoardDetail boardDetail; ... } //자식 @Entity public class BoardDetail{ @Id private Long boardId; @MapsId //BoardDetail.boardId 매핑 @OneToOne @JoinColumn(name="BOARD_ID") private Board board; .... } //일대일 식별관계의 저장 public void save() { Board board = new Board(); board.setTitle("제목); em.persist(board); BoardDetail boardDetail = new BoardDetail(); boardDetail.setContent("내용"); boardDetail.setBoard(board); em.persist(boardDetail); }
- BoardDetail처럼 식별자가 단순히 컬럼 하나면 @MapsId를 사용하고 속성값은 비워둔다.
10) 식별, 비식별 관계의 장단점
- 다음과 같은 설계 관점에서 식별 관계보다는 비식별 관계를 선호한다.
- 식별 관계는 부모 테이블의 기본 키를 자식 테이블로 전파하면서 자식 테이블의 기본 키 컬럼이 점점 늘어난다.
- 조인할 때 SQL이 복잡해지고 기본 키 인덱스가 불필요하게 커질 수 있다.
- 식별 관계는 2개 이상의 컬럼을 합해서 복합 기본 키를 만들어야 하는 경우가 많다.
- 식별 관계는 비즈니스 의미가 있는 자연키 컬럼을 조합하는데, 시간이 지나면 변화에 대처하기 힘들다.
- 비식별 관계의 기본키는 비즈니스와 전혀 관계 없는 대리키를 주로 사용한다.
- 식별 관계는 별도의 복합 키 클래스를 만들어서 사용해야 하므로 노력이 많이 든다.
- 비식별 관계의 기본 키는 @GenerateValue 처럼 편리하게 만들 수 있다.
- 식별 관계는 특정 상황에 조인 없이 하위 테이블 검색만으로 완료할 수 있는 장점이 있다.
- 비식별 관계를 사용하고 기본키는 Long 타입의 대리키를 사용하는 것이 추천된다.
- 선택적 비식별 관계 보다는 필수적 비식별 관계를 사용하는 것이 좋다(NULL 허용 때문)
4. 조인 테이블
1) 조인 테이블
- 데이터베이스 테이블의 연관관계를 설정하는 방법은 크게 '조인 컬럼 사용'(외래키), '조인 테이블 사용' 2가지다.
- 조인 컬럼 사용
- 회원이 사물함을 사용하기 전 까지는 MEMBER 테이블의 LOCKER_ID 외래 키에 null을 입력 해 두어야 한다.
- 외래 키에 null을 허용하는 관계를 선택적 비식별 관계라 한다.
- 선택적 비식별 관계는 외래 키에 null을 허용하므로 OUTER JOIN을 사용해야 한다.
- 조인 테이블 사용
- MEMBER_LOCKER 와 같은 별도의 테이블을 사용해서 연관관계를 관리한다.
- MEMBER 와 LOCKER에는 외래 키 컬럼이 없다.
- 회원이 락커를 사용할 때 MEMBER_LOCKER 테이블에만 값을 추가하면 된다.
- 단점은 테이블이 늘어나고, JOIN 을 위해 MEMBER_LOCKER 테이블 까지 추가 조인해야 한다.
- JPA에서 조인 컬럼은 @JoinColumn 으로, 조인 테이블은 @JoinTable 로 매핑한다.
- 조인 테이블은 주로 다다대 관계를 일대다, 다대일 관계로 풀어내기 위해 사용한다.
2) 일대일 조인 테이블
- 일대일 관계를 만들려면 조인 테이블의 외래 키 컬럼 각각에 총 2개의 유니크 제약조건을 걸어야 한다.
//부모 @Entity public class Parent{ @Id @GeneratedValue @Column(name="PARENT_ID") private Long id; private String name; @OneToOne @JoinTable(name="PARENT_CHILD", joinColumns=@JoinColumn(name="PARENT_ID"), inverseJoinColumns=@JoinColumn(name="CHILD_ID") ) private Child child; ... } //자식 @Entity public class Child{ @Id @GeneratedValue @Column(name="CHILD_ID") private Long id; private String name; ... }
- 부모 엔티티에 @JoinColumn 대신 @JoinTable을 사용했다.
- name: 매핑할 조인 테이블 이름
- joinColumns: 현재 엔티티를 참조하는 외래 키(PARENT_CHILD 테이블)
- inverseJoinColumns: 반대방향 엔티티를 참조하는 외래 키(PARENT_CHILD 테이블)
- 양방향 매핑은 다음 코드를 추가하면 된다.
public class Child{ ... @OneToOne(mappedBy="child") private Parent parent; }
3) 일대다 조인 테이블
- 일대다 관계를 만들려면 조인 테이블의 컬럼중 다(N)와 관련된 컬럼인 CHILD_ID에 유니크 제약을 걸어야 한다.
//부모 @Entity public class Parent{ @Id @GeneratedValue @Column(name="PARENT_ID") private Long id; private String name; @OneToMany @JoinTable(name="PARENT_CHILD", joinColumns=@JoinColumn(name="PARENT_ID"), inverseJoinColumns=@JoinColumn(name="CHILD_ID") ) private List<Child> child = new ArrayList<Child>(); ... } //자식 @Entity public class Child{ @Id @GeneratedValue @Column(name="CHILD_ID") private Long id; private String name; ... }
4) 다대일 조인 테이블
- 다대일은 일대다에서 방향만 반대이다.
//부모 @Entity public class Parent{ @Id @GeneratedValue @Column(name="PARENT_ID") private Long id; private String name; @OneToMany(mappedBy="parent") private List<Child> child = new ArrayList<Child>(); ... } //자식 @Entity public class Child{ @Id @GeneratedValue @Column(name="CHILD_ID") private Long id; private String name; @ManyToOne(optional=false) @JoinTable(name="PARENT_CHILD", joinColumns=@JoinColumn(name="CHILD_ID"), inverseJoinColumn=@JoinColumn(name="PARENT_ID") ) private Parent parent; ... }
5) 다대다 조인 테이블
- 다대다 관계를 만들려면 조인 테이블의 두 컬럼을 합해서 하나의 복합 유니크 제약 조건을 걸어야 한다.
//부모 @Entity public class Parent{ @Id @GeneratedValue @Column(name="PARENT_ID") private Long id; private String name; @ManyToMany @JoinTable(name="PARENT_CHILD", joinColumns=@JoinColumn(name="PARENT_ID"), inverseJoinColumns=@JoinColumn(name="CHILD_ID") ) private List<Child> child = new ArrayList<Child>(); ... } //자식 @Entity public class Child{ @Id @GeneratedValue @Column(name="CHILD_ID") private Long id; private String name; ... }
- 조인 테이블에 컬럼을 추가하면 @JoinTable 전략을 사용할 수 없다. 새로운 엔티티를 만들어서 조인 테이블과 매핑
해야 한다.
6) 엔티티 하나에 여러 테이블 매핑
- @SecondaryTable을 사용하면 한 엔티티에 여러 테이블을 매핑할 수 있다.
@Entity @Table(name="BOARD") @SecondaryTable(name="BOARD_DETAIL", pkJoinColumns=@PrimaryKeyJoinColumns(name="BOARD_DETAIL_ID")) public class Board{ @Id @GeneratedValue @Column(name="BOARD_ID") private Long id; private String title; @Column(table="BOARD_DETAIL") private String content; ... }
- Board 엔티티는 @Table을 사용해서 BOARD 테이블과 매핑했다
- @SecondaryTable을 사용해서 BOARD_DETAIL 테이블을 추가로 매핑했다.
- @SecondaryTable.name: 매핑할 다른 테이블의 이름
- @SecondaryTable.pkJoinColumns: 매핑할 다른 테이블의 기본 키 속성
- contetn 필드는 @Column(table="BOARD_DETAIL") 을 사용해서 매핑했다.
- title 필드처럼 테이블을 지정하지 않으면 기본 테이블인 BOARD에 매핑된다.
- 더 많은 테이블을 매핑하려면 @SecondaryTables 를 사용하면 된다.
@SecondaryTables({ @SecondaryTable(name="BOARD_DETAIL"), @SecondaryTable(name="BOARD_FILE") })
- @SecondaryTable을 사용해서 두 테이블을 하나의 엔티티에 매핑하는 방법 보다는 테이블당 엔티티를 각각 만들어
서 일대일 매핑하는 것을 권장한다.
'IT > JPA' 카테고리의 다른 글
고급 주제와 성능 최적화 (0) 2021.02.28 웹 애플리케이션과 영속성 관리 (0) 2021.01.24 값 타입 (0) 2020.12.29 연관관계 매핑 (0) 2020.12.08 JPA 의 영속성 관리 (0) 2020.11.29