queryDSL 기초(조인, 서브쿼리, case, 상수)
조인
기본 조인
사용방법
join( 조인할 대상, 별칭으로 사용할 Q Type)
예시
1 | //member와 team의 QType static import한 상태 |
- join(), innerJoin() : inner join
- leftJoin() : left outer join
- rightJoin() : right outer join
세타 조인 (연관관계가 없는 조인)
사용방법
from() 절에 조인하고자 하는 대상 (연관관계가 없는) 엔티티를 선택하여 넣어주면 돼!
예시
1 | List<Member> result = queryFactory |
외부조인(위의 일반조인 설명에서 제공되어지는 left outer or right outer)은 안돼!!
but, 조인 on 을 이용하면 똑같은 효과를 볼 수 있어. 즉 외부조인 형태가 가능해져.
조인 + on 절
사용방법
join().on() 형태로 체이닝 걸어서 사용하면 돼
조인 대상 필터링 할때 사용
1 | List<Tuple> result = queryFactory |
참고로 내부조인을 사용하면서 대상에 대해 필터링을 하기위해 on절에 조건을 거는 것은 where 절에 조건을 거는 것과 동일해.
즉 내부 조인이면 익숙하게 where 절에 필터링 조건을 넣어주는 것이 편하겠지.
연관관계가 없는 엔티티의 외부 조인을 원할 때 사용
1 | //회원의 이름과 팀의 이름이 같은 대상 외부 조인 원하는 경우 |
- 하이버네이트 1.5버전부터 on 절을 이용하여 서로 관계가 없는 필드로 외부 조인하는게 가능해졌데.
- 위에서 보듯이 일반 Join과는 조금 문법이 달라.
페치조인
사용방법
join().fetchJoin() 이런 식으로 체이닝 해주면 돼!!
예시
1 | Member findMember = queryFactory |
- 패치 조인은 잘 알겠찌만 sql에서 제공하는 기능은 아니고, sql join을 이용해서 연관된 엔티티를 한꺼번에 가져오고 싶을 때 사용하는 기능이야.
서브쿼리
사용방법
com.querydsl.jpa.JPAExpressions를 사용해서 원하는 서브쿼리를 작성하면 돼!
예시
1 | //where 절에서 서브쿼리 사용하기 |
위처럼 select 절과 where 절에서 서브쿼리를 사용할 수 있지만 from절에서는 사용하지 못해!!
why..? jpa의 jpql에서 지원하지 않아!! 결국 queryDsl은 jpql로 변환이 될거고 jpql에서 지원하지 않는 기능은 지원하지 못해!!
그럼 어떻게 하느냐?? from 절에 서브쿼리가 필요한 경우는 아래로 대체
- 서브쿼리를 join으로 변경 시도 (가능한 상황도 있지만 불가능할수도..)
- 어플리케이션의 쿼리를 2번 분리해서 실행
- nativeSQL을 사용
Case 문
단순한 경우
예시
1 | List<String> result = queryFactory |
참고로 DB에서는 raw데이터를 그루핑 하거나 필터링 할 순 있겠지만 최소화 시켜야해!!
디비에서 이러한 부분들을 맡는 것은 좋지 않데.
즉, 위 경우면 가져온 데이터를 바탕으로 어플리케이션에서 10이면 열살, 20이면 스무살 이런식으로 하는게 좋다는거지.
복잡한 경우
복잡한 경우에는 CaseBuilder() 라는 놈을 따로 사용해주면 돼!!
1 | List<String> result = queryFactory |
만약에 특정 case에 대해 순서를 부여하고 싶다면??
예를들어서 아래와 같은 조건의 경우
- 0~30 살이 아닌 회원 가장 먼저 출력
- 0~20 살 회원 출력
- 21~30 살 회원 출력
1 | NumberExpression<Integer> rankPath = new CaseBuilder() |
상수, 문자 더하기
상수
사용방법
queryDsl에서 제공하는 Expressions.constant(xx) 사용하면 돼!!
예시
1 | Tuple result = queryFactory |
문자 더하기
사용방법
.concat() 을 체이닝해주면 돼!
예시
1 | String result = queryFactory |
위 예시에서 member.age.stringValue()를 보자.
java는 타입이 정해져있는 언어이기에 저런식으로 string으로 변환을 해주어야해.
stringValue()를 통해 문자가 아닌 타입을 문자로 변환할 수 있는데 자주 쓰인다니 기억!! (Enum을 처리할 때)