[자바 ORM 표준 JPA] JPQL 다형성 쿼리(Polymorphic Query)
[자바 ORM 표준 JPA] JPQL 다형성 쿼리(Polymorphic Query)
JPQL 다형성 쿼리(Polymorphic Query)
이번 시간에는 다형성 쿼리에 대해 정리를해 보겠습니다.
다형성 쿼리#
JPA가 이러한 다형성을 위해 제공하는 특수한 기능들이 있습니다.
TYPE#
조회 대상을 특정 자식으로 한정
예) Item 중에 Book, Movie를 조회해라
[JPQL]
SELECT i FROM Item i
WHERE TYPE(i) IN (Book, Movie)
[SQL]
SELECT i.* from Item i
WHERE i.DTYPE IN ('B', 'M')
TREAT (JPA2.1)#
- 자바의 타입 캐스팅과 유사 (다운 캐스팅 : 자식 타입으로 캐스팅)
- 상속 구조에서 부모 타입을 특정 자식 타입으로 다룰 때 사용
- FROM, WHERE, SELECT(하이버네이트 지원) 사용
예) 부모인 Item과 자식 Book이 있다.
[JPQL]
SELECT i FROM Item i
WHERE TREAT(i AS Book).author = 'Kim'
[SQL]
SELECT i.* from Item i
WHERE i.DTYPE = 'B' and i.author = 'Kim'
자식과 부모의 어떤 전략으로 구성이 되어있느냐에 따라 SQL이 다르게 나가게 되며, 해당 SQL문은 싱글 테이블 전략 시 나오는 쿼리
이전 소스#
실전 예제 프로젝트 jpa-shop 프로젝트의 소스
Item.java
package jpabasic.jpashop.domain;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn
public abstract class Item extends BaseEntity{
public Item(){
}
public Item(String name, int price, int stockQuantity) {
this.name = name;
this.price = price;
this.stockQuantity = stockQuantity;
}
@Id @GeneratedValue
@Column(name="ITEM_ID")
private Long id;
private String name;
private int price;
private int stockQuantity;
@ManyToMany(mappedBy = "items")
private List<Category> categories = new ArrayList<>();
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;
}
public int getStockQuantity() {
return stockQuantity;
}
public void setStockQuantity(int stockQuantity) {
this.stockQuantity = stockQuantity;
}
}
Album.java
package jpabasic.jpashop.domain;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorValue("A")
public class Album extends Item{
private String artist;
private String etc;
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public String getEtc() {
return etc;
}
public void setEtc(String etc) {
this.etc = etc;
}
}
Book.java
package jpabasic.jpashop.domain;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorValue("B")
public class Book extends Item{
private String author;
private String isbn;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
}
Movie.java
package jpabasic.jpashop.domain;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorValue("M")
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;
}
}