QueryDsl - JPQLQuery 사용하기

givepro·2022년 1월 17일
1

spring boot

목록 보기
1/2

QueryDsl이란?

Querydsl은 HQL(Hibernate Query Language) 쿼리를 타입에 안전하게 생성 및 관리할 수 있게 해주는 프레임워크다. 공식 레퍼런스를 인용한 정의인데, 잘 와닿지 않는다면 Querydsl은 자바 코드 기반으로 쿼리를 작성하게 해준다”라고 생각해도 좋을 것 같다.

QueryDsl을 왜 사용하는가?

JPA를 사용해서 페이지를 구현하다보면 기본 문법으로 구현하지 못하는 쿼리들이 있다. ex) 통계 쿼리

스프링부트에서는 Entity의 기본적인 CRUD가 가능하도록 JpaRepository 인터페이스를 제공한다
save() findAll() delete() ...

이를 해결하기 위해서는 몇가지의 방법들이 있다.

  • Java8 Stream
  • NativeQuery
  • JPQL
  • QueryDsl

모두 현재 처리하고자하는 작업에는 문제가 없으나 확장성에 가장 적합한 QueryDsl을 사용한다.

QueryDSL의 장점은 다양한 조건의 쿼리를 생성할 수 있다는 장점이 있습니다.
( Optional 한 쿼리 조건을 각각 적용 가능)

QueryDsl에 JPQLQuery을 활용하여 구현

1. QuerydslRepositorySupport 구현

사용하고자 하는 엔티티의 querydsl을 아래와 같이 생성
return 타입은 TestPlaceCount Class를 생성하여 처리했다.

import static com.develop.hello.domain.QTest.test;

@Repository
public class TestSupport extends QuerydslRepositorySupport {

    public TestSupport() {
        super(Test.class);
    }

    public List<TestPlaceCount> getPlaceCountSum() {
        JPQLQuery<TestPlaceCount> query = from(test)
                .groupBy(test.place)
                .select(Projections.constructor(TestPlaceCount.class,
                        test.place,
                        test.count.sum()
        ));

        return query.fetch();
    }
}

2. Data class 생성

import com.querydsl.core.annotations.QueryProjection;
import lombok.Data;

@Data
public class TestPlaceCount {

    @QueryProjection
    public TestPlaceCount(String place, Integer countSum) {
        this.place = place;
        this.countSum = countSum;
    }

    private String place;
    private Integer countSum;

}

코드는 위 내용으로 사실상 끝이났다. 알아보기전까지는 어려움이 많았으나 실제 사용된 코드는 간결했다. 오히려 이를 활용하면 확장성 뿐만아니라 일반 nativeQuery와는 다르게 가독성이 너무 훌륭하기 때문이다.

작업을 하면서 Projections.constructor() 이 부분이 좀 막혔으나 이 말을 생성 Data Class의 constructor로 사용한다는 것을 명시하는 구문이다. 그래서 TestPlaceCount.class 추가

3. 사용

public String getMainView(Model model) {
... 생략
	model.addAttribute("placeCountList", seoulMuseumResultSupport.getPlaceCountSum());
... 생략
}

그동안 이러한 쿼리들은 nativeQuery를 사용해서 처리했었는데 앞으로 queryDsl을 활용하는것이 더 마음에 들어서 자주 사용해볼 생각이다.

profile
server developer

0개의 댓글