beadss / jpa-study

jpa슽터디입니다
1 stars 2 forks source link

7장 정리중 #17

Open 2xel opened 5 years ago

2xel commented 5 years ago

7. 고급 매핑

1. 상속 관계 매핑

1.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 {...}

2. MappedSuperclass

@MappedSuperclass
public abstract class BasreEntity {
    @Id @GeneratedValue
    private Long id;
    private String name;
    ...
}

@Entity
public class Member extends BaseEntity {
    // ID 상속
    // NAME 상속
    private String email;
    ...
}

@Entity
public class Seller extends BaseEntity {
    // ID 상속
    // NAME 상속
    private String shopName;
    ...
}
@Entity
@AttributeOverride(name = "id", column = @Column(name = "MEMBER_ID"))
public class Member extends BaseEntity {...}
@Entity
@AttributeOverrides({
    @AttributeOverride(name = "id", column = @Column(name = "MEMBER_ID")),
    @AttributeOverride(name = "name", column = @Column(name = "MEMBER_ID"))
})
public class Member extends BaseEntity {...}

3. 복합 키와 실벽 관계 매핑

3.1 식별관계 vs 비식별 관계

식별 관계

비식별 관계

3.2 복합 키 : 비식별 관계 매핑

// 기본키 1개
@Entity
public class Hello {
    @Id
    private String id;
}

// 기본키 2개 이상이면 이렇게 하면 될거 같지만..
@Entity
public class Hello {
    @Id
    private String id1;
    @Id
    private String id2; // 실행 시점에 매핑 예외 발생
}

@IdClass

// 부모 클래스
@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) {...}

    @Override
    public int hashCode() {...}
}
// 저장코드
Parent parent = new Parent();
parent.setId1("myId1");
parent.setId2("myId2");
parent.setName("parentName");
em.persist(parent);
// 조회코드
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;
}

`@EmbeddedId

@IdClass가 데이터베이스에 맞춘 방법이라면 @EmbeddedId는 좀 더 객체지향적인 방법이다.

@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, hashCode 구현
    ...
}
// 저장
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);

복합 키와 equals(), hashCode()

ParentId id1 = new ParentId();
id1.setId1("myId1");
id1.setId2("myId2");

ParentId id2 = new ParentId();
id2.setId1("myId1");
id2.setId2("myId2");

id1.equals(id2);

IdClass vs @EmbeddedId

em.createQuery("select p.id.id1, p.id.id2 from Parent p");  // @EmbeddedId
em.createQuery("select p.id1, p.id2 from Parent p");        // @IdClass

3.3 복합키: 식별 관계 매핑

@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;

    private String name;
    ...
}

// 자식 ID
public class ChildId implements Serializable {
    private String parent;  // Child.parent 매핑
    private String childId; // Child.childId 매핑

    // equlas, hashCode
    ...
}

// 손자
@Entity
@IdClass(GrandChildId.class)
public class GrandChild {
    @Id
    @ManyToOne
    @JoinColumn({@JoinColumn(name = "PARENT_ID"), @JoinColumn(name = "CHILD_ID")})
    private Child child;

    @Id @Column(name = "GRANDCHILD_ID")
    private String id;

    private String name;
    ...
}

// 손자 ID
public class GrandChildId implements Serializable {
    private ChildId child;  // GrandChild.child 매핑
    private String id;      // GrandChild.id 매핑

    // equlas, hashCode
    ...
}

@EmbeddedId와 식별 관계

3.4 비식별 관계로 구현

3.5 일대일 식별 관계

3.6 식별, 비식별 관계의 장단점

4. 조인 테이블

조인 컬럼 사용(외래 키)

조인 테이블 사용(테이블)

4.1 일대일 조인 테이블

4.2 일대다 조인 테이블

4.3 다대일 조인 테이블

4.4 다대다 조인 테이블

7.5 엔티티 하나에 여러 테이블 매핑

@Entity
@Table(name="BOARD")
@SecondaryTable(name = "BOARD_DETAIL", pkJoinColumns = @PrimaryKeyJoinColumn(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;
    ...
}
2xel commented 5 years ago
  1. @EmbeddedId JPQL에서 id.id1의 방식으로 접근가능한데, 꼭 엔티티 형태로만 가져올 수 만 있을까?
  2. GeneratedKey가 primitive면 어떻게 할까? = null 허용
  3. @DiscriminatorValue의 기본값은? = 클래스명