개발놀이터

JPA 상속관계 매핑 본문

JPA/JPA

JPA 상속관계 매핑

마늘냄새폴폴 2021. 8. 23. 18:53

*상속관계 매핑

테이블을 설계하는것에 있어서 공통된 칼럼이 계속 등장하면 어떻게해야할까? 방법은 크게 세가지로 나눌 수 있다.
1. 한 테이블에 다 때려박는 SINGLE_TABLE 전략
2. 각 테이블에 중복되는 칼럼을 그냥 집어넣는 TABLE_PER_CLASS 전략
3. 슈퍼타입와 서브타입를 이용하는 JOINED 전략


*JOINED 전략
관계형 데이터베이스에는 상속관계라는 것이 없다. 하지만 비슷한 모델링이 있는데 바로 슈퍼타입 서브타입이다. 예를 들어서 앨범, 책, 영화 테이블에 각각 공통 칼럼인 이름과 가격을 슈퍼타입인 아이템 테이블에 다 담는 것이다. 그리고 서브타입인 앨범, 책, 영화에는 슈퍼클래스의 PK값을 PK,FK값으로 사용함으로써 추후에 서브타입를 찾으려 할때는 조인을 사용해서 찾을 수 있게끔 만든다.

JPA로 구현할 때는 객체가 상속을 사용하듯이 설계하면 된다. 예를 들어 앨범, 책, 영화를 자식클래스로, 아이템이라는 부모클래스에는 필드에 이름과 가격을 넣고 extends로 마무리 지어주면 된다. 그리고 부모 클래스에는 @Inheritence(strategy = InheritanceType.JOINED)라는 어노테이션을 추가해주면 된다. 기본값이 InheritanceType.SINGLE_TABLE이기 때문에 전략을 적어넣어 주지 않으면 1번처럼 한 테이블에 모든 칼럼을 다 때려박게 된다. 

@Inheritence 어노테이션과 같이 넣어줘야 하는 어노테이션이 있는데 바로 @DiscriminatorColumn이다. 부모 테이블에 넣어야 하며, 이 어노테이션을 넣게 되면 슈퍼타입에 DTYPE이라는 칼럼이 들어오게 되는데 이 칼럼의 값으로 서브타입의 테이블명이 들어오게 된다. 나중에 select쿼리로 찾을 때 이게 어디랑 연결된 데이터인지 쉽게 알아보게 하기 위해서 넣어주는 것이 좋다. @DiscriminatorValue라는 어노테이션도 있는데, 이 어노테이션은 자식클래스에 적는 것이다. 자식 클래스에 예를 들어 @DiscriminatorValue("M") 이라고 적으면 DTYPE에 들어가는 값이 테이블명이 아니라 지정해둔 문자열로 들어간다. 회사 지침상 바꿔야하는 경우도 있으므로 알아두자

JOINED 전략의 장점
1. 테이블이 정규화 되어있다.
2. 외래 키 참조 무결성 제약조건 활용이 가능하다.
3. 저장공간이 효율화되어있다.

JOINED 전략의 단점
1. 테이블을 여러개 사용해야 하기 때문에 INSERT 나 SELECT를 함에 있어서 SINGEL_TABLE전략보다 성능이 떨어질 수 있다.
2. 테이블이 여러개이기 때문에 복잡하다


*SINGLE_TABLE 전략
테이블 하나에 모든 칼럼을 다 집어넣고 DTYPE으로 구분하는 방법, 프로젝트가 별로 크지 않거나 JOINED전략이 복잡하다고 생각이 되면 이 싱글테이블 전략을 사용하는 것도 나쁘지 않은 선택이 될 것이다. 

SINGLE_TABLE 전략의 장점
1. 조인이 필요 없으므로 일반적으로 조회 성능이 빠름
2. 조회 쿼리가 단순함

SINGLE_TABLE 전략의 단점
1. 자식 엔티티가 매핑한 칼럼은 모두 NULL을 허용해야한다. (치명적인 단점)
2. 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있어서 상황에 따라서 조회 성능이 오히려 느려질 수 있다.

 

 

 

cf)@MappedSuperclass 어노테이션이 있는데 이것은 상속관계 매핑이 아니라 단순히 테이블에서 중복으로 사용하고 싶은 속성이 있을 때 ORM 개발자 기준에서 좀 더 객체지향적으로 설계할 수 있는 어노테이션이다. 만약 기본적인 CRUD에서 DBA가 모든 CRUD에 누가 했는지, 언제 했는지, 마지막 변경은 누가했는지, 마지막 변경이 언제인지 데이터 분석을 위해서 모두 추가해달라고 요청이 들어왔다고 가정해보면, 모든 테이블에 해당 속성을 전부 추가해야 한다. 하지만 이런 중복은 개발자들이 가장 피하고싶은 상황인데 그럴때 등장하는 것이 바로 @MappedSuperclass이다. 예를들어 부모 클래스인 BaseEntity에 속성을 집어넣고 클래스레벨의 어노테이션에서 @MappedSuperclass를 매핑한다. 그렇게 되면 이 부모 클래스를 사용하고 싶은 자식 클래스에 extends BaseEntity만 해주면 해당 테이블에 값이 전부 다 들어가게 된다. 

 

@MappedSuperclass 정리
1. 상속관계 매핑 X
2. 엔티티 X, 테이블과 매핑 X
3. 부모 클래스를 상속 받는 자식 클래스에 매핑 정보만 제공
4. 조회, 검색 불가
5. 직접 생성해서 사용할 일이 없으므로 추상 클래스를 권장한다.

6. 테이블과 관계 없고, 단순히 엔티티가 공통으로 사용하는 매핑 정보를 모으는 역할
7. 주로 등록일, 수정일, 등록자, 수정자 같은 전체 엔티티에서 공통으로 적용하는 정보를 모을 때 사용
8. 참고 : @Entity 클래스는 엔티티나 @MappedSuperclass로 지정한 클래스만 상속이 가능하다.

'JPA > JPA' 카테고리의 다른 글

값 타입  (0) 2021.08.26
지연로딩과 즉시로딩 (프록시)  (0) 2021.08.24
JPA 연관관계의 주인  (0) 2021.08.23
JPA 기본키 매핑  (0) 2021.08.21
JPA Entity 매핑  (0) 2021.08.21