티스토리 뷰

관계형 데이터베이스는 상속 관계가 없다.

슈퍼타입 서브탕입 관계라는 모델링 기법이 객체의 상속과 비슷하다

상속관계 매핑 : 객체의 상속과 구조, DB의 슈퍼타입 서브타입 관계를 매핑한다.

 

1. 조인전략

package inheritancemapping;


import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Item {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private int price;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}
package inheritancemapping;

import javax.persistence.Entity;

@Entity
public class Movie extends Item{
    private String director;
    private String actor;

    public String getDirector() {
        return director;
    }

    public void setDirector(String director) {
        this.director = director;
    }

    public String getActor() {
        return actor;
    }

    public void setActor(String actor) {
        this.actor = actor;
    }
}
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class main {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("x");
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try {
            Movie movie = new Movie();
            movie.setDirector("Director A");
            movie.setActor("Actor A");
            movie.setName("Movie A");

            em.persist(movie);


            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            em.close();
            emf.close();
        }
    }
}

Item class와 Item 을 상속받은 Movie 클래스가 있을 때 아래와 같이 Movie를 넣게되면 Item 과 Movie에 각각 insert 하게 된다.

 

이제 find를 해보면

Movie findMovie = em.find(Movie.class, 1L);
System.out.println(findMovie.getName());

join쿼리가 실행되는 것을 볼 수 있다.

item class에 @DiscriminatorColumn 를 붙여주게 되면 DTYPE 컬럼이 생기게 된다.

자식클래스에는 @DiscriminatorValue 를 붙일 수 있다.

데이터베이스에서 Item에 Movie 타입인 것을 알 수 있게 된다.

장점

  • 테이블 정규화
  • 외래키 참조 무결성 제약조건 활용 가능
  • 저장공간 효율화

단점

  • 조회 시 조인을 사용, 성능 저하
  • 조회 쿼리가 복잡
  • 삽입 시 insert query 가 2번 실행

 

 

2. Single Table

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
을 Item에 붙여주면

Item 컬럼이 있고 Item table에 자식클래스의 속성을 모두 넣는다.

 

다른 클래스의 속성은 null로 들어가있다.

join이 없으니 성능상의 이점이 있다.

 

장점

  • 조인이 없으므로 일반적으로는 빠름
  • 조회 쿼리가 단순

단점

  • 자식 엔티티가 매핑한 컬럼은 모두 null 허용
  • 단일테이블이기 때문에 테이블이 커지고 성능저하가 일어날 수 있다.

 

 

3.  TABLE_PER_CLASS

 부모클래스의 속성을 자식클래스의 속성으로 모두 내려서 클래스가 만들어져있다. 이렇게 할 때는 부모 클래스를 abstract class로 만들면 데이터베이스에 부모 클래스가 아예 생성 되지 않는다.

문제는 테이블을 완전히 분리해두었기 때문에 id만 아는경우 모든 테이블을 union해서 찾게 된다.

장점

  • 서브타입을 명확하게 구분해서 처리
  • not null 제약조건 사용 가능

단점

  • 여러 자식테이블을 함께 조회하기 때문에 성능이 느림
  • 자식 테이블을 통합해서 쿼리하기 어렵다

 

 

매핑정보 상속 : @MappedSuperclass

공통 매핑정보가 사용할 때 사용한다.

객체 끼리 공통된 속성을 BaseEntity로 뽑아서 사용

데이터베이스는 여전히 분리되어 있음.

 

package inheritancemapping;

import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;

@MappedSuperclass
public class BaseEntity {
    private String createdBy;
    private LocalDateTime createdDate;
    private String updatedBy;
    private LocalDateTime updatedDate;
}

BaseEntity 클래스가 있고 상속받은 Another 클래스가 있다.

 

package inheritancemapping;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Another extends BaseEntity{

    @Id
    @GeneratedValue
    private Long id;

    public void setId(Long id) {
        this.id = id;
    }

    public Long getId() {
        return id;
    }
}

테이블은 이렇게 생성된다.

이 때 Another, Item, Item을 상속받은 Movie를 살펴보면 BaseEntity.의 속성이 모두 들어가있다.

 

 

상속관계 매핑이 아니다.

엔티티도 아니고, 테이블과 매핑되지도 않는다.

부모클래스를 상속받는 자식 클래스에 매핑 정보만 제공한다.

직접 생성해서 사용할 일이 없으므로 추상클래스가 권장된다.

실제 데이터베이스에 생성되지 않는다.(이번 경우 BaseEntity 클래스는 디비에 나타나지 않는다)

 

테이블과 관계없고 단순히 엔티티가 공통으로 사용하는 매핑 정보를 모으는 역할

주로 등록일, 수정일, 등록자, 수정자 같은 전체 엔티티에서 공통으로 적용하는 정보를 모을 때 사용

참고: @Entity 클래스는 엔티티나 @MappedSuperclass 로 지정한 클래스만 상속 가능

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함