✍상속관계 매핑
- 관계형 DB는 상속 관계가 없음.
- 슈퍼타입 서브타입 관계라는 모델링 기법이 객체 상속과 유사.
-> 객체의 상속과 DB의 슈퍼타입 서브타입 관계를 매핑
조인 전략
- 상위 테이블과 그를 상속받는 구조의 하위 테이블을 만들고 하위 테이블의 PK, FK를 같도록 설계하여 JOIN으로 두 테이블을 가져오는 전략.
단일 테이블 전략
- 논리 모델을 한 테이블로 합치는 전략. (성능적으로 고려하기도 함 단순해서.)
구현 클래스마다 테이블 전략
- 공통되는 특성을 각 테이블에 추가하여 상위 테이블 개념을 없애는 전략. (중복되는 컬럼 존재.)
=> JPA는 세가지 전략을 모두 지원. 세 전략은 DB에서 테이블이 어떻게 구성되는지에 따른 차이가 있음.
클래스 설계를 바꿀 필요 없이 전략만 바꿔주면 해당 전략에 따라 JPA가 자동으로 테이블을 구성해줌.
상위 Entity에 @Inheritance 어노테이션을 붙여, 상속관계 매핑.
💡 조인전략 = @Inheritance(strategy = InheritanceType.JOINED)
상위 테이블과 하위 테이블을 생성하여 JOIN하는 전략. (일반적으로 사용하는 전략)
하위 Entity객체를 생성하고 데이터를 추가하면 상위 테이블도 같이 생성되어, INSERT 쿼리가 2개가 나감.
즉, 테이블이 2개가 생성됨. 이후, 조회할 때 JOIN까지 JPA가 자동으로 해줌.
장점 - 테이블이 정규화 되어있다. 저장공간 효율화.
단점 - 조인을 많이 사용하여 쿼리가 복잡함, INSERT 쿼리 2번 호출
출처 - https://www.inflearn.com/course/ORM-JPA-Basic/dashboard
💡 단일 테이블 전략 = @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
Entity를 DB에 저장할 때, 하위 테이블의 컬럼들을 합쳐서 상위 테이블 1개만 생성.
성능 측면에서 가장 좋음. JOIN 없이, 조회 가능. (단순한 테이블 구성 시 좋은 전략 / 기본 값)
- @DiscriminatorColumn 어노테이션 없이도 DTYPE 컬럼이 생성됨.
(어떤 타입으로 생성되었는지 유일하게 알 수 있는 방법이기 때문.)
장점 - JOIN을 사용하지 않아, 조회 성능이 빠름
단점 - 자식 엔티티가 매핑한 컬럼은 모두 null 허용 (데이터 무결성 위배)
출처 - https://www.inflearn.com/course/ORM-JPA-Basic/dashboard
✂ 구현 클래스마다 테이블 전략 = @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
데이터베이스 설계자와 ORM 전문가 둘 다 추천하지 않는 전략.
상위 Entity의 컬럼을 하위 Entity 클래스에 내려, 테이블을 구성하는 방식.
중복 컬럼이 생기고 각 타입별 테이블이 각각 생성됨.
상위 테이블이 생성되지 않기 위해서는 abstract 클래스로 설계하는 것이 맞음.
장점 - not null 제약조건 사용 가능
단점 - UNION SQL사용으로 여러 하위 테이블을 조회할 때 성능이 느림, 테이블 추가 시 쿼리를 전부 다시 짜야하는 경우가 발생.
출처 - https://www.inflearn.com/course/ORM-JPA-Basic/dashboard
@DiscriminatorColumn = Entity의 컬럼으로 DTYPE을 생성해줌. (Default로 DTYPE에는 하위 Entity 명이 들어가게됨.)
=> DB입장에서는 해당 데이터가 어떤 목적으로 생성되었는지 알 수 없어, 추가해주는 것이 좋음.
=> 하위 Entity에서 @DiscriminatorValue("DTYPE 명") 을 지정하면 상위 Entity의 DTYPE에 지정한 이름이 삽입됨.
@MappedSuperClass
- 공통된 속성만 상속받아 사용할 때 사용.
- 상속관계 매핑 X, 엔티티 X, 테이블과 매핑 X => 매핑 정보만 제공하는 클래스이기 때문에 조회, 검색 불가.
=> 직접 사용할 일이 없으므로, abstract 클래스로 정의하는 것을 권장.
본 게시글은 김영한님의 Inflearn 강의를 토대로 제작되었습니다.