728x90
반응형
JPA 객체 참조특성으로 JOIN이 되더라도 연관관계로만 데이터를 못가져 오는 경우,
JPQL에서 인위적으로 JOIN을 걸어야하는 상황이 발생할때가 있습니다.
기본적인 쿼리는 아래와 같습니다.
SELECT
project.*,
user_project.*,
project_part.*
FROM project
LEFT JOIN user_project
ON (user_project.project_no = project.project_no)
AND (user_project.user_no = 1)
LEFT JOIN project_part
ON (project_part.project_part_no = user_project.project_part_no);
3개의 테이블을 JOIN해서 데이터를 모두 가져오거나 원하는 데이터만 촉촉 뽑는경운데요.
JPQL코드로 작성해보겠습니다.
@Query("SELECT p,up FROM Project p " +
"LEFT JOIN fetch UserProject up ON (up.id = p.id) " +
"LEFT JOIN fetch ProjectPart pp ON (pp.id = up.id) " +
"where up.projectUser.email = 'webdevyoo@gmail.com'")
List<Project> findJoinedProjectTest1();
이렇게 되면 하이버네이트를 통해 쿼리상의 조회결과 자체는 3개 엔터티를 모두 JOIN하고 원하는 테이블인 Project와 UserProject 데이터를 모두 가져오긴 합니다.
하지만 반환타입이 List의 제너릭 Project이므로 Project데이터만 가져올수밖에 없습니다.
Project와 UserProject 엔터티를 모두 가져올 수 있는 방법은 제가 알아본 바로는 3가지가 있습니다.
1. JQPL 조회시 DTO로 직접 변환
2. 제너릭 타입을 Object[]로 반환 이후 Strem.map등을 활용하여 DTO로 변환
3. 제너릭 타입을 Tuple로 반환 이후 Strem.map등을 활용하여 DTO로 변환
1번 예시코드
@Query("SELECT NEW io.codertown.web.dto.JoinedProjectDto(p, up) FROM Project p " +
"LEFT JOIN fetch UserProject up ON (up.id = p.id) " +
"LEFT JOIN fetch ProjectPart pp ON (pp.id = up.id) " +
"where up.projectUser.email = 'webdevyoo@gmail.com'")
List<JoinedProjectDto> findJoinedProjectTest1();
장점 : 바로 변환이 가능하다.
단점 : 풀 패키지 경로를 작성해야 하므로 JPQL쿼리문이 지저분해진다
2번 예시코드
@Query("SELECT p, up FROM Project p " +
"LEFT JOIN fetch UserProject up ON (up.id = p.id) " +
"LEFT JOIN fetch ProjectPart pp ON (pp.id = up.id) " +
"where up.projectUser.email = 'webdevyoo@gmail.com'")
List<Object[]> findJoinedProjectTest2();
3번 예시코드
@Query("SELECT pt AS pt, up AS up FROM Project pt " +
"LEFT JOIN fetch UserProject as up ON (up.id = pt.id) " +
"LEFT JOIN fetch ProjectPart as pp ON (pp.id = up.id) " +
"where up.projectUser.email = 'webdevyoo@gmail.com'")
List<Tuple> findJoinedProjectTest3();
3가지 실험을 모두 해봤을때 속도가 가장 잘나오는것은 2번째 방법입니다.
2,3번방법1번 방법은 5배가까이 차이가납니다.
1번방법 | 2번방법 | 3번방법 | |
01회차 | 81 | 23 | 25 |
02회차 | 91 | 21 | 23 |
03회차 | 92 | 23 | 26 |
04회차 | 119 | 24 | 27 |
05회차 | 99 | 21 | 23 |
06회차 | 108 | 22 | 23 |
07회차 | 80 | 22 | 19 |
08회차 | 81 | 19 | 21 |
09회차 | 89 | 21 | 27 |
10회차 | 90 | 22 | 22 |
평균 | 93 | 21.8 | 23.6 |
728x90
반응형