작성
·
279
답변 2
6
이에 대한 결과가 궁금해서 '상속관계 매핑' 에서 진행했던 예제를 토대로 직접 실습을 진행해봤습니다.
다음은 Main 함수 코드입니다.
try {
Book book = new Book();
book.setName("bookA");
book.setAuthor("babo");
em.persist(book);
em.flush();
em.clear();
List<Item> result = em.createQuery("SELECT i FROM Item i WHERE TYPE(i) = Book", Item.class)
.getResultList();
for (Item item : result) {
Book book1 = (Book) item;
System.out.println("book1.getName() = " + book1.getName());
System.out.println("book1.getAuthor() = " + book1.getAuthor());
}
tx.commit();
} catch (Exception e) {
tx.rollback();
e.printStackTrace();
} finally {
em.close();
emf.close();
}
}
그런 다음 상속 전략을 JOIN, SINGLE_TALBE, TABLE_PER_CLASS으로 바꿔가며 쿼리 결과를 살펴봤습니다. (참고로 @DiscriminatorColumn 값은 기본값인 DTYPE, 나머지 테이블의 @DiscriminatorValue 값은 앞 글자의 대문자로 설정하였습니다.)
LEFT JOIN을 하면서 ITEM의 DTYPE이 'B'인 조건을 만족하는 값을 찾는 SELECT 쿼리가 실행되는 것을 확인할 수 있었습니다.
Hibernate:
/* SELECT
i
FROM
Item i
WHERE
TYPE(i) = Book */ select
item0_.id as id2_5_,
item0_.name as name3_5_,
item0_.price as price4_5_,
item0_1_.artist as artist1_1_,
item0_2_.author as author1_2_,
item0_2_.isbn as isbn2_2_,
item0_3_.actor as actor1_9_,
item0_3_.director as director2_9_,
item0_.DTYPE as dtype1_5_
from
Item item0_
left outer join
Album item0_1_
on item0_.id=item0_1_.id
left outer join
Book item0_2_
on item0_.id=item0_2_.id
left outer join
Movie item0_3_
on item0_.id=item0_3_.id
where
item0_.DTYPE='B'
book1.getName() = bookA
book1.getAuthor() = babo
SINGLE_TABLE 전략은 ITEM 테이블에 모든 값이 저장되므로 조인의 과정없이 ITEM의 DTYPE이 'B'인 조건을 만족하는 값을 찾는 SELECT 쿼리가 발생하는 것을 확인할 수 있었습니다.
Hibernate:
/* SELECT
i
FROM
Item i
WHERE
TYPE(i) = Book */ select
item0_.id as id2_3_,
item0_.name as name3_3_,
item0_.price as price4_3_,
item0_.artist as artist5_3_,
item0_.author as author6_3_,
item0_.isbn as isbn7_3_,
item0_.actor as actor8_3_,
item0_.director as director9_3_,
item0_.DTYPE as dtype1_3_
from
Item item0_
where
item0_.DTYPE='B'
book1.getName() = bookA
book1.getAuthor() = babo
UNION을 통한 어마무시한 SELECT 쿼리가 발생한 것을 확인할 수 있었습니다. 그러나 위의 두 전략과는 다르게 DTYPE을 통해 만족하는 조건을 찾는 것이 아니라 'clazz_' 라는 속성을 통해 만족하는 조건을 찾는 것을 확인할 수 있었습니다. 이 clazz_는 TABLE_PER_CLASS 전략을 사용할 때만 생성되는 것 같았고, FROM 절의 서브 쿼리를 보면 Album, Book, Movie 테이블에 각각 clazz_의 값이 1, 2, 3으로 설정되는 것을 확인할 수 있었습니다.
Hibernate:
/* SELECT
i
FROM
Item i
WHERE
TYPE(i) = Book */ select
item0_.id as id1_5_,
item0_.name as name2_5_,
item0_.price as price3_5_,
item0_.artist as artist1_1_,
item0_.author as author1_2_,
item0_.isbn as isbn2_2_,
item0_.actor as actor1_9_,
item0_.director as director2_9_,
item0_.clazz_ as clazz_
from
( select
id,
name,
price,
artist,
null as author,
null as isbn,
null as actor,
null as director,
1 as clazz_
from
Album
union
all select
id,
name,
price,
null as artist,
author,
isbn,
null as actor,
null as director,
2 as clazz_
from
Book
union
all select
id,
name,
price,
null as artist,
null as author,
null as isbn,
actor,
director,
3 as clazz_
from
Movie
) item0_
where
item0_.clazz_=2
book1.getName() = bookA
book1.getAuthor() = babo
JOINED, SINGLE_TABLE, TABLE_PER_CLASS 전략 모두 상속관계에서 TYPE 연산을 통해 특정 자식 클래스를 조회할 수 있었습니다. 그러나 JOINED, SINGLE_TABLE 전략은 DTYPE을 사용하고, TABLE_PER_CLASS는 clazz_ 라는 속성(?)을 사용합니다.
실습 내용이 많이 부족하고 어설프기 때문에 잘못된 점이나 부족한 점 있으면 많이 조언 남겨주세요 😅
넵 답변 감사합니다.
강의의 코드를 따라치면서 듣다 보면 어느 순간부터는 그냥 기계적으로 타이핑하기에 급급할 뿐이고 내용에 대한 이해는 제대로 이뤄지지 않더라구요.
그래서 일단은 따라치지 않고 시청만 하면서 내용을 익힌 후 다시 한 번 돌려보면서 따라쳐보고 실습해보는 나름의 방식대로 학습을 진행하는 중입니다.
사실 직접 쳐보면 금방 알 수 있는 내용이란 걸 알면서도 이전부터 따라와놓은 코드가 없어서 질문을 드렸습니다;ㅎ
1회독(?)은 이제 거의 끝나가니 위 내용은 2회차 때에 실습해보도록 하겠습니다.
감사합니다^^