스프링부트/JPA

[Spring] Query DSL 문법 정리

삼록이 2025. 8. 26. 09:27

쿼리 DSL은

JPA환경에서 복잡한 쿼리같은 경우 JPQL 문자열을 직접 써야하나, 단순 문자열이라 오타나 에러가 컴파일 시점에 체크가 안되어 불편하다. 그래서  QueryDSL은 JPQL을 자바 코드처럼 작성할 수 있는 라이브러리로 JPA와 함께 사용되면 장점이 매우 크다.

 

QueryDSL 설정방법은 아래 게시글을 참고하면 된다.

https://gotopm.tistory.com/54

 

[Spring] JPA환경에서 검색 및 필터 기능 구현 2 - QueryDSL 방법 이용

이전 게시물에서 Specification을 통해, 즉 CriteriaAPI를 통해 검색 및 필터 기능을 구현했다면 이번에는 같은 기능을 QueryDSL을 통해 구현하도록 리팩토링 해보려한다. (이전 게시물) [JPA] JPA환경에서

gotopm.tistory.com

 

 

 

QueryDSL을 사용하면 컴파일 시점에서 @Entity라고 어노테이션을 붙여놓은 즉 , 엔티티 클래스들은 Q클래스라는 형태로 자동 생성된다. Q클래스는 QueryDSL 전용 클래스라고 생각하면 된다.

하나의 또 다른 클래스가 생긴것이고 클래스이기 때문에 오타나 에러가 있을 경우 컴파일 시점에 오류가 체크 되고 , 또 인텔리제이 같은 IDE에서는 자동 완성도 지원되는 것이다.

 

그래서 QueryDSL 문을 쓰는데에 있어서는 항상 먼저 Q클래스로 부터 객체를 가지고 와야한다,

그래서 아래 보면 Quser user = QUser.user 라고 먼저 선언이 되는 것이다.

이 말은 User 엔티티를 QueryDSL에서 사용할 QUser 객체를 준비한다 라는 뜻으로 이해하면 되겠다.


 

1.전체 조회

QUser user = QUser.user;

List<User> result = queryFactory
        .selectFrom(user)   // SELECT * FROM user
        .fetch();

selectFrom은 테이블 전체를 조회.

fetch()는 결과를 List로 반환

 

select 조회쿼리는 fetch 계열 메서드를 붙여야 실제 실행이된다.

*update/delete 수정/삭제 쿼리는 execute()메서드를 붙여야 실행이 된다.

 

  • .fetch() → 결과 리스트 반환
  • .fetchOne() → 단건 반환
  • .fetchFirst() → 첫 번째만 반환
  • .fetchCount() → 카운트만 반환

-fetchOne()

User result = queryFactory
        .selectFrom(user)
        .where(user.id.eq(1L))
        .fetchOne();

 

정확히 결과값으로 한 건만 기대할 때 사용되며 결과가 없다면 null이 반한된다.

결과가 한 건이 아닌 2건 이상이 되면 예외(NonUniqueResultException)가 발생한다

 

-fetchFirst()

User result = queryFactory
        .selectFrom(user)
        .orderBy(user.age.desc())
        .fetchFirst();

 

여러 건 중에서도 첫 번째 결과 하나만 반환하게 된다.

결과가 없으면 null이 반환된다.

목록 중에서 제일 위에 것만 필요하다고할 때 fetchFirst()를 쓰면 될 것이다.

 

-fetchCount()

long count = queryFactory
        .selectFrom(user)
        .fetchCount();

 

결과 값의 "개수"를 반환한다.

SQL에서 SELECT COUNT(*)라고 보면 된다.

QueryDSL 5점대 버전 이상에서는 Deprecated되어, fetch().size()나 fetch().size().count()를 권장한다고 한다.

 

2.필요 칼럼만 조회

List<String> result = queryFactory
        .select(user.name,user.age)   // SELECT name,age
        .from(user)
        .fetch();

 

3.WHERE 조건

List<User> result = queryFactory
        .selectFrom(user)
        .where(user.name.eq("홍길동"))   // WHERE user.name = '홍길동'
        .fetch();
  • eq()  : =
  • ne() : !=
  • lt() : <
  • loe(): <=
  • gt() : >
  • goe() :>=
  • between(x,y) : 사이
  • in(...) : IN조건
  • LIKE("%길동%") : LIKE 조건 

 

4.정렬

List<User> result = queryFactory
        .selectFrom(user)
        .orderBy(user.age.desc())   // ORDER BY age DESC
        .fetch();

asc() : 오름차순

desc() : 내림차순