백엔드 기술은 SpringBoot + Spring Data JPA를 조합해서 사용하는데, 이 조합으로 해결하지 못하는 한계점이 바로 복잡한 쿼리 즉, 동적 쿼리를 짜야할 때이다!
이런 문제를 해결해주는 것이 Querydsl이다!
Querydsl은
쿼리를 자바 코드로 작성할 수 있고 문법 오류를 컴파일 시점에 확인할 수 있다.
동적 쿼리 문제를 해결해준다.
SQL과 문법이 유사하여 쉽게 학습할 수 있다.
Querydsl + Spring Data JPA -> 개발이 즐거워진다!
Querydsl + Spring Data JPA 장점
단순 반복 X (쿼리도 코드로)
Querydsl은 단순히 JPQL Builder 이다! 따라서 JPA의 특징들 (ex. 지연로딩)
JPQL vs Querydsl (W. 영한님)
JPQL이 제공하는 모든 검색 쿼리 조건
eq : '=' 조건
ne : '!=' 조건 (eq과 not의 조합으로도 동일한 조건 걸 수 있음!)
ex) 아래의 두 조건식은 동일하다!
member.username.ne("member1")
member.username.eq("member1").not()
isNotNull : null이 아니다.
in(1, 10) : 'in 조건' 1, 10 중 하나라도 해당
notIn(1, 10) : 'in 조건'의 not 1, 10 중 하나라도 아닌 경우
between(1, 10) : 'between 조건` 1 ~ 10에 포함
like("member") : 'like 검색' member와 정확히 일치하는 값 검색
contains("member") : 'like %member% 검색', member라는 단어가 포함된 값 검색
startsWith("member") : 'like member% 검색' member로 시작되는 값 검색
goe : greater than equal
gt : greater than
loe : lower than equal
lt : lower than
결과 조회
* fetch() : 리스트 조회, 없으면 빈 리스트 반환
* fetchOne() : 단건 조회
* 결과가 없으면 null
* 결과가 둘 이상있으면, `com.querydsl.core.NonUniqueResultException` 예외 발생
* fetchFirst() : `limit(1).fetchOne()`
* fetchResults() : 페이징 정보 포함, total count 쿼리 추가 실행
* fetchCount() : count 쿼리로 변경해서 count 수 조회
참고)
더보기
실제 content를 가지고 오는 쿼리와 실제 total count를 가지고 오는 쿼리가 다를 경우가 있다. 복잡하고 성능이 중요한 곳에서의 페이징 쿼리는 이 함수를 쓰면 안된다. 이런 경우에는 쿼리 두 개를 따로 날리는 것이 좋다.
정렬 순서
내용이 간단해서 테스트 예제로 대체
/**
* 회원 정렬 순서
* 1. 회원 나이 내림차순 (DESC)
* 2. 회원 이름 올림차순 (ASC)
* 단, 2에서 회원 이름이 없으면 마지막에 출력(nulls last)
*/
@Test
internal fun sort() {
entityManager.persist(Member(null, age = 100))
entityManager.persist(Member("member5", age = 100))
entityManager.persist(Member("member6", age = 100))
val result = queryFactory.selectFrom(member)
.where(member.age.eq(100))
.orderBy(
member.age.desc(),
member.username.asc().nullsLast(), // nullFirst()도 있음
)
.fetch()
assertThat(result[0].username).isEqualTo("member5")
assertThat(result[1].username).isEqualTo("member6")
assertThat(result[2].username).isNull()
}