이 글은 인프런 김영한님의 Spring 강의를 바탕으로 개인적인 정리를 위해 작성한 글입니다.
상속관계 매핑
관계형 데이터베이스는 상속관계라는 개념이 존재하지 않는다.
RDB에서는 슈퍼타입 서브타입 관계라는 모델링 기법이 객체 상속과 유사한 개념이다.
상속관계 매핑이란 객체의 상속 구조와 DB의 슈퍼타입 서브타입 관계를 매핑하는 것을 뜻한다.
상속관계 매핑은 총 2가지 전략이 있다.
- 조인 전략
- 단일 테이블 전략
기본적으로 조인 전략을 선택하되, 성능이 우선시된다면 단일 테이블 전략 선택
@Inheritance
상속 매핑 전략을 설정하여 상위 클래스와 이를 상속받는 하위 클래스 간의 데이터 저장 방식을 지정할 수 있다. @Inheritance 애노테이션은 상위 클래스에 사용되며, 상속 매핑 전략으로 단일 테이블 전략, 조인 전략, 테이블 퍼 클래스 전략을 제공한다.
strategy: 상속 매핑 전략을 지정하며, InheritanceType.SINGLE_TABLE, InheritanceType.JOINED 중 하나를 선택할 수 있다.
@Inheritance(strategy = InheritanceType.JOINED)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn
상위 클래스와 이를 상속받은 하위 클래스 간의 데이터 구분을 위해 사용된다. 이 애노테이션은 단일 테이블 전략이나 조인 전략에서 사용되며, 특정 컬럼을 기준으로 엔티티 타입을 구분한다.
주요 속성
- name: 테이블에 저장될 컬럼의 이름을 지정한다.
@DiscriminatorColumn(name = "DTYPE")// 기본이 "DTYPE"
조인 전략
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
public class Item {
@Id @GeneratedValue
private Long id;
private String name;
private int price;
//getter and setter...
}
@Entity
public class Movie extends Item{
private String director;
private String actor;
//getter and setter...
}
@Entity
@DiscriminatorValue("MyAlbum")//DTYPE 컬럼에 저장될 이름 지정
public class Album extends Item{
private String artist;
//getter and setter...
}
@Entity
public class Book extends Item{
private String Author;
private String isbn;
//getter and setter...
}
public class Main {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
Movie movie = new Movie();
movie.setDirector("aaaa");
movie.setActor("bbbb");
movie.setName("바람과 함께 사라지다.");
movie.setPrice(10000);
Album album = new Album();
album.setArtist("Rebugs");
album.setPrice(2000);
album.setName("JPA");
em.persist(movie);
em.persist(album);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}
장점
- 테이블 정규화
- 외래 키 참조 무결성 제약조건 활용가능
- 저장공간 효율화
단점
- 조회시조인을많이사용,성능저하
- 조회 쿼리가 복잡함
- 데이터 저장시 INSERT SQL 2번 호출
단일 테이블 전략
Item 테이블만 변경, 나머지는 모두 그대로
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)//변경된 부분
@DiscriminatorColumn
public class Item {
@Id @GeneratedValue
private Long id;
private String name;
private int price;
//getter and setter...
}
장점
- 조인이 필요 없으므로 일반적으로 조회 성능이 빠름
- 조회 쿼리가 단순함
단점
- 자식 엔티티가 매핑한 컬럼은 모두 null 허용
- 단일테이블에모든것을저장하므로테이블이커질수있다.상 황에 따라서 조회 성능이 오히려 느려질 수 있다.
@MappedSuperclass
- 상속관계 매핑X
- 엔티티X, 테이블과 매핑X
- 부모 클래스를 상속 받는 자식 클래스에 매핑 정보만 제공
- 조회, 검색 불가(em.find(BaseEntity) 불가)
- 직접 생성해서 사용할 일이 없으므로 추상 클래스 권장
- 테이블과 관계 없고, 단순히 엔티티가 공통으로 사용하는 매핑 정보를 모으는 역할
- 주로 등록일, 수정일, 등록자, 수정자 같은 전체 엔티티에서 공통으로 적용하는 정보를 모을 때 사용
- 참고: @Entity 클래스는 엔티티나 @MappedSuperclass로 지정한 클래스만 상속 가능
@MappedSuperclass
public abstract class BaseEntity {
private String createBy;
private LocalDateTime createdDate;
private String lastModifiedBy;
private LocalDateTime lastModifiedDate;
//getter and setter...
}
@Entity
public class Member extends BaseEntity{ //상속
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long ID;
@Column(name = "USERNAME")
private String username;
@ManyToOne
@JoinColumn(name = "TEAM_ID", insertable = false, updatable = false)
private Team team;
}
@Entity
public class Team extends BaseEntity{ //상속
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
@OneToMany
@JoinColumn(name = "TEAM_ID")
private List<Member> members = new ArrayList<>();
}
'Java Category > JPA' 카테고리의 다른 글
[JPA] 즉시 로딩, 지연 로딩, 영속성 전이, 고아 객체 (0) | 2024.07.27 |
---|---|
[JPA] 프록시(Proxy) (0) | 2024.07.26 |
[JPA] 다양한 연관관계 매핑 (5) | 2024.07.24 |
[JPA] 연관관계 매핑(단방향, 양방향)을 통한 객체 그래프 탐색 (0) | 2024.07.17 |
[JPA] 엔티티 매핑(Entity Mapping) (1) | 2024.07.16 |