728x90

Java 에서 말하는 상속 개념이 SQL 에서는 존재하지는 않지만 Jpa 를 사용하여 상속 전략 을 사용하여 두 객체관의 관계를 매핑 하고 상속 관계 전략을 구현한 여러개의 Entity 를 Querydsl 을 사용하여 select 해보겠습니다.

 

https://ict-nroo.tistory.com/128

 

[JPA] 상속관계 매핑 전략(@Inheritance, @DiscriminatorColumn)

상속관계 매핑 객체는 상속관계가 존재하지만, 관계형 데이터베이스는 상속 관계가 없다.(대부분) 그나마 슈퍼타입 서브타입 관계라는 모델링 기법이 객체 상속과 유사하다. 상속관계 매핑이라

ict-nroo.tistory.com

 

부모 Entity

@Getter
@Entity
@Inheritance(strategy = SINGLE_TABLE)
@DiscriminatorColumn(name = "BOOK_MARK_TYPE")
public abstract class Bookmark {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "bookmark_id")
    private Long id;
    @ManyToOne(fetch = LAZY, cascade = ALL)
    @JoinColumn(name = "member_id")
    private Member member;

}

 

상위 아이템으로 북마크 라는 Entity 를 만들고 하위 계층으로 각각의 아이템북마크를 만들어서 Bookmark 라는 Entity 를 상속 받겠습니다.

 

@Getter
@DiscriminatorValue("BLOG")
@Entity
public class BlogBookmark extends Bookmark {

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "blog_id")
    private Blog blog;
}
@Getter
@DiscriminatorValue("CAFE")
@Entity
public class CafeBookmark extends Bookmark {

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "Cafe_id")
    private Cafe cafe;
}

 

blog 와 cafe 북마크 라는 하위 아이템을 만들고 Bookmark를 상속 받았습니다.

 

QueryDsl 에서 의 사용법

queryFactory.selectFrom(bookmark)
.leftJoin(blogBookmark).on(blogBookmark.eq(bookmark))
.leftJoin(cafeBookmark).on(cafeBookmark.eq(bookmark))
.fetch();

 

QEntity 객체를 상위 부모로 두고 Entity 객체도 결국 자바의 Class 인만큼 상속받은 객체의 field를 참조 할 수 없습니다.

그래서 명시적으로 join 으로 하위 객체를 불러줘야 합니다.

 

형변환

fetch 로 데이터를 가져오게 되면 List<Bookmark> 의 타입의 배열로 결과를 받게 됩니다.

 

하지만 모든 북마크를 조회 하였을때 형변환이 필요하다면 어떻게 해야할까요?

 

if (bookmark instanceof BlogBookmark) {
    BlogBookmark blogBookmark = (BlogBookmark) bookmark;
    return blogBookmark.toDto();
}
if (bookmark instanceof CafeBookmark) {
    CafeBookmark cafeBookmark = (CafeBookmark) bookmark;
    return cafeBookmark.toDto();
}

 

이런식으로 타입을 체킹 하여 형변환과 dto로 변환하여 사용 할 수 있습니다.

728x90