[QueryDSL] 기본 문법
QueryDSL은 Query Domain Specific Language의 약자로 간단하게 JPQL을 만들어주는 역할을 한다고 생각하면 된다.
@Test
public void startJPQL() {
String qlString =
"select m from Member m " +
"where m.username = :username";
Member findMember = em.createQuery(qlString, Member.class)
.setParameter("username", "member1")
.getSingleResult();
assertThat(findMember.getUsername()).isEqualTo("member1");
}
@Test
public void startQuerydsl() {
JPAQueryFactory queryFactory = new JPAQueryFactory(em);
// Factory는 Test 밖으로 빼서 사용할 수 있다. (동시성 문제는 트랜잭션마다 em이 할당되니 괜찮음)
QMember m = new QMember("m");
Member findMember = queryFactory
.select(m)
.from(m)
.where(m.username.eq("member1"))//파라미터 바인딩 처리
.fetchOne();
assertThat(findMember.getUsername()).isEqualTo("member1");
}
QueryDSL을 사용하면 JPQL도 위와 같이 자바 코드를 사용해서 작성할 수 있다.
내부적으로 QMember 클래스를 생성해서 사용하는데, 위의 QMember는 static import 등으로 줄여서 사용할 수 있다.
JPAQueryFactory 객체를 사용해 적절한 JPQL을 빌드하는 방식으로 동작한다.
1. 검색
where 내부에 검색 조건을 and와 or로 메서드 체인으로 연결할 수 있다.
JPQL이 지원하는 모든 검색 조건을 factory에서 쉽게 사용할 수 있다.
2. 결과 조회
fetch / fetchOne / fetchFirst / fetchResults / fetchCount 등 Factory가 제공하는 메서드를 사용해 결과를 원하는 방식으로 조회할 수 있다.
fetchResults와 fetchCount 메서드는 Deprecated 메서드로 QueryDSL 기술이 추후 지원하지 않을 가능성이 있는 메서드이니, 웬만하면 해당 기능을 별도로 작성해서 사용하도록 하자.
3. 정렬
desc, asc로 내림차순 또는 올림차순을 설정하고 nullsLast, nullsFirst로 null 데이터의 순서를 설정한다.
자바의 Comparable 인터페이스를 정의하는 것과 비슷하다. 정렬 1순위, 1순위가 같으면 다음으로 비교할 2순위 등을 설정한다.
4. 페이징
offset과 limit를 설정해서 페이징을 구현한다.
5. 집합
가져오는 데이터의 타입이 여러 가지인 경우 Tuple을 사용해서 받아온다. (DTO를 이용해도 괜찮음)
JPQL이 제공하는 모든 집합 함수를 사용할 수 있고 groupoBy 메서드를 사용해 그룹 단위로도 조회할 수 있다.
6. 조인
join(대상, 별칭으로 사용되는 Q타입) 으로 사용한다.
연관관계가 없는 요소들을 조인하는 세타 조인도 가능하다. (싹다 가져온 후 where로 걸러내는 방식)
on 문법을 사용해 외부 조인 조인 대상을 필터링 할 수 있다.
Member는 모두 가져오는데, Team은 이름이 teamA인 Team만 가져온다.
내부 조인에서 on 문법을 사용하는 경우 where 문법을 사용하는 경우와 같으니 외부 조인이 필요한 경우에서만 on 문법을 사용하자.
서로 관계 없는 필드로 외부 조인할 때도 on 문법을 사용할 수 있다.
leftJoin() 함수의 인자로 엔티티 하나만 들어감에 주의하자.
일반 조인에서는 leftJoin 함수의 인자로 멤버와 연관된 Team을 넣어주지만 on 조인에서는 조인 대상을 바로 넣어주고 on 문법에서 조건을 설정한다.
7. 페치 조인
join 메서드에 fetchJoin 메서드를 추가해 페치 조인을 사용한다.
Member를 조회할 때 연관된 Team도 함께 조회한다.
8. 서브 쿼리
SQL내부에 SQL을 포함하는 방식으로 쿼리를 작성할 수 있다.
alias의 중복을 피하기 위해 QMember를 새로 생성해줬다.
위의 코드는 Member 중 나이가 가장 많은 사람을 조회한다.
eq 문법으로 특정 요소와 동일한 요소를 선택하고, goe를 사용해서 특정 요소보다 큰 요소를 선택하도록 설정할 수 있다.
JPA를 공부할 때 알 수 있었듯 JPA에서는 select 나 where에서는 서브쿼리는 가능하지만 from 에서는 서브쿼리를 사용할 수 없고, QueryDSL도 마찬가지이다.
이런 경우 서브쿼리를 Join으로 바꾸거나 쿼리 2번으로 분리하는 방법을 시도해보고, 최후의 수단으로 네이티브 쿼리를 사용하자.
9. CASE
CASE 문법도 when과 then으로 처리할 수 있다.
'Spring > QueryDSL' 카테고리의 다른 글
[QueryDSL] 활용 (Spring Data JPA + QueryDSL) (1) | 2023.01.11 |
---|---|
[QueryDSL] 활용 (JPA + QueryDSL) (0) | 2023.01.11 |
[QueryDSL] 중급 문법 (0) | 2023.01.10 |
댓글
이 글 공유하기
다른 글
-
[QueryDSL] 활용 (Spring Data JPA + QueryDSL)
[QueryDSL] 활용 (Spring Data JPA + QueryDSL)
2023.01.11 -
[QueryDSL] 활용 (JPA + QueryDSL)
[QueryDSL] 활용 (JPA + QueryDSL)
2023.01.11 -
[QueryDSL] 중급 문법
[QueryDSL] 중급 문법
2023.01.10