QueryMethod, JPQL, QueryDSL 중에서 어떤것을 사용할까
항상 개발할때 마다
QueryMethod, JPQL, QueryDSL 중에서
어떤 상황에서 어떤걸 사용해야 할지 몰라서, 아무거나 기분 내키는 대로 선택해서 사용하곤 했다.
그 중에서도
조회/검색/필터링 기능은
JPQL, QueryDSL을 사용해서 개발하였다.
기술 선택의 근거와 명분이 없는 잘못된 방식인걸 알지만,,,
개발에 급급하느라 그냥 그런거 신경안쓰고 아무거나 골라쓰는 경우가 태반이었다...
JPQL을 사용해도 되고, QueryDSL을 사용해도 되는데,
상황별로 어떤 기준을 갖고, 어떤 기술스택을 사용해야 할지 명확히 정리가 된거같지 않아서
내 나름대로 정리를 하고, 구현해보려고 한다.
이 3가지 방법들은
Spring Data JPA를 사용하면서, 데이터베이스 쿼리를 작성하는 데 활용되는 대표적인 방법들이다.
QueryMethod
Spring Data JPA에서 제공하는 기능으로, 메서드 이름을 기반으로 쿼리를 자동 생성해주는 아주 편리한 기능이다.
아래처럼 findById로 메서드 이름을 정의하면, JPA가 이를 파싱해서 적절한 SQL 쿼리로 변환한다.
별도의 쿼리 작성 없이 간단한 규칙에 따라 메서드 이름만으로 동작한다.
QueryMethod는
간단한 CRUD 작업이나 기본적인 조건 검색이 필요한 경우에 사용하는 것이 좋을 것이다.
ex > 특정 필드 값으로 조회(findByUsername), 정렬(findByUsernameOrderByCreatedDateDesc), 범위 검색(findByAgeBetween) 등등.
복잡한 조인이나 동적 쿼리가 필요 없는 경우에 적합하다!
장점 | 단점 |
코드 작성이 간단해서 생산성이 증가한다. | 메서드 이름이 길어질수록 가독성이 심하게 떨어진다 (findByNameAndAgeGreaterThanAndCityLikeOrderByDateDesc) -> 이게 QueryMethod 이름이다 ㅋㅋㅋ |
쿼리를 직접 작성할 필요가 없어서 실수를 줄일 수 있다.(당연..) | 복잡한 쿼리(다중 조인, 서브쿼리, 동적쿼리)는 표현 불가능 하다. |
JPQL (Java Persistence Query Language)
JPA에서 제공하는 객체 지향 쿼리 언어로, 엔티티 객체를 조회한다.
SQL과 유사하지만 테이블과 컬럼이 아니라
엔티티와 필드를 사용하여 쿼리를 작성한다.
아래처럼
@Query 어노테이션을 사용해서 쿼리를 작성한다.
public interface UserRepository extends JpaRepository<User, String> {
@Query("FROM Account WHERE email = :email")
List<User> findByName(@Param("name") String name);
}
위 코드는, user엔티티로 부터 name(필드)과 일치하는 유저들을 조회하는 쿼리를 날리는 것이다.
QueryMethod로는 표현하기 어렵고,
복잡한 쿼리가 필요한 경우(조인, 그룹화, 서브쿼리 등)에 사용하기 좋다.
정적인 쿼리를 작성할 때 적합하다.
장점 | 단점 |
복잡한 쿼리를 비교적으로 명확하게 작성 가능하다. | 쿼리를 문자열로 작성하므로 런타임에만 오류를 발견할 수 있다. |
엔티티 기반으로 작성하므로 데이터베이스와 독립적이다 | 동적쿼리를 처리하려면 문자열 조합이 필요해서 코드가 더러워질 수 있다. |
QueryDSL
타입-세이프(type-safe)하게 쿼리를 작성하도록 지원해주고,
SQL 형태가 아닌 자바코드로 작성해서 데이터베이스 쿼리 작성을 쉽고 안전하게 만들어주는 라이브러리이다.
Q클래스(엔티티 기반으로 생성된 쿼리타입)를 사용해서 쿼리를 구성한다.
( QUser.user.age.eq(20)와 같은 식으로 )
동적 쿼리가 필요한 경우(검색 조건이 유동적으로 변하는 상황)에 사용하는 것이 좋고,
타입 안전성을 보장하고 싶은 경우,
복잡한 조인, 서브쿼리, 집계 함수 등이 포함된 쿼리 작업을 할 때, 사용하는 것이 유리하다.
장점 | 단점 |
컴파일 타임에 오류를 잡을 수 있다. | 초기 설정(Q클래스 생성을 위한 빌드설정)이 조금 복잡하다. |
동적쿼리를 깔끔하고 직관적으로 작성가능하다. | JPQL, QueryMethod에 비교해서 러닝커브가 높다. |
그래서 나는,
간단한 조회 작업이고, 빠르게 개발해야하는 상황에서는 -> QueryMethod
QueryMethod로는 해결할 수 없고, 조금 복잡한 쿼리가 필요한 경우, (동적 쿼리 조건이 거의 없는 경우) -> JPQL
검색 조건이 동적으로 변하는 동적쿼리인 경우(필터링 옵션이 많은 경우), 타입안정성이 필요한 경우 -> QueryDSL
이런식으로 구분하여 3개중 적절한 방법을 선택해서 사용할 것이다.

이미 알고있는 사실이겠지만, 정답은 존재하지 않는다.
자신의 개발상황과 프로젝트 규모, 팀의 기술수준에 따라서 적절한 방법을 선택해서 사용하면 될것이다.
3개 중 1개만 사용하라는 법도 없고, 3개 모두를 사용해도 된다.
(간단한건 QueryMethod, 복잡한 쿼리는 queryDSL 과 같은 식으로..)
그러니 현재 나에게 적절한 방법을 선택해서 사용하도록 하자!