해당 코드는 Github를 확인해주세요.
step-12: 페이징 API 만들기 에서 JPA와 Pageable
를 이용해서 간단한 페이징 API를 만들었습니다. 이번 포스팅에서는 Query Dsl 동적 쿼리를 이용해서 검색 페이징 API를 만들어 보겠습니다.
기초 작업
Maven을 기준으로 설명드리겠습니다. 아래의 코드를 pom.xml
에 추가하고 mvn compile
을 진행합니다.
1 | <dependency> |
complie이 성공적으로 완료되면 target/generated-sources/java
디렉토리에 QXXX
클래스 파일 생성되는 것을 확인할 수 있습니다.
Controller
1 |
|
- type은
AccountSearchType
enum으로 검색 페이징을 위한 type을 의미합니다. 본 예제에서는 이메일, 이름, 전체 페이징 기능을 제공합니다. value
는 type에 대한 value를 의미합니다. 이메일 검색시에는 value에 검색하고자하는 값을 지정합니다.PageRequest
는 step-12: 페이징 API 만들기에서 사용한 객체를 그대로 사용 하면 됩니다.
검색을 위한 type은 String
객체로 관리하는 것보다 enum
으로 관리하는 것이 훨씬 효율적이라고 생각합니다. 만약 위에서 지정한 type 이외의 값을 요청할 경우 예외처리, Service
영역에서 추가적인 처리 등 다양한 관점에서 enum
이 훨씬 효율적입니다.
Service
1 |
|
QuerydslRepositorySupport
를 이용하면 동적 쿼리를 쉽게 만들수 있습니다. 객체 기반으로 쿼리를 만드는 것이라서 타입 세이프의 강점을 그대로 가질 수 있습니다. QuerydslRepositorySupport
추상 클래스를 상속 받고 기본 생성자를 통해서 조회 대상 엔티티 클래스를 지정합니다.
search(...)
메서드는 컨트롤러에서 넘겨 받은 type
, value
, pageable
를 기반으로 동적 쿼리를 만드는 작업을 진행합니다.
QueryDsl에서 생성한 QAccount
객체를 기반으로 동적 쿼리 작업을 진행합니다. switch
문을 통해서 각 타입에 맞는 쿼리문을 작성하고 있습니다. 우리가 일반적으로 작성하는 쿼리와 크게 다르지 않아 해당 코드는 이해하기 어렵지 않습니다. 이것이 QueryDsl이 갖는 장점이라고 생각합니다.
NAME
타입인 경우에는 firstName
, lastName
에 대한 like 검색을 진행합니다. ALL
같은 경우에는 이전에 작성했던 전체 페이징과 동일합니다.
요청
NAME
타입으로 yun
으로 요청을 합니다. firstName
or lastName
에 yun
이 들어가 있는 계정을 검색 합니다.
응답
1 | { |
SQL
1 | select |
리스트 조회에 대한 쿼리는 반드시 해당 쿼리가 어떻게 출력되는지 반드시 확인해야 합니다. 해당 객체는 연관관계 설정이 되어 있지 않아 N + 1문제가 발생할 여지가 없지만, 실무에서는 많은 객체와의 관계를 맺기 때문에 반드시 쿼리가 어떻게 동작하는지 확인해야 합니다.