Spring Boot - QueryDSL

김명식·2023년 5월 17일
0

Spring Boot

목록 보기
6/11
post-thumbnail

QueryDSL

QueryDSL자바를 위한 동적 쿼리 작성을 위한 오픈 소스 라이브러리이다.
때문에 SpringBoot에 기본 내장하고 있지 않기 때문에 따로 프로젝트에 추가를 해줘야한다.

pom.xml

<!--querydsl-->
<dependency>
	<groupId>com.querydsl</groupId>
    	<artifactId>querydsl-apt</artifactId>
</dependency>
<dependency>
	<groupId>com.querydsl</groupId>
    <artifactId>querydsl-jpa</artifactId>
</dependency>
<dependency>
	<groupId>com.querydsl</groupId>
    <artifactId>querydsl-sql</artifactId>
</dependency>


<plugin>
	<groupId>com.mysema.maven</groupId>
    <artifactId>apt-maven-plugin</artifactId>
    <version>1.1.3</version>
    <executions>
    	<execution>
        	<goals>
            	<goal>process</goal>
            </goals>
            <configuration>
                <outputDirectory>target/generated-sources/java</outputDirectory>
                <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                <options>
                	<querydsl.generatedAnnotationClass>com.querydsl.core.annotations.Generated</querydsl.generatedAnnotationClass>
                </options>
            </configuration>
		</execution>
	</executions>
</plugin>

위 의존성을 pom.xml에 추가한 뒤

pom.xml -> Maven -> Generate Sources and Update Folders를 누르면
프로젝트의 target -> generated-sources -> java 폴더 안에
기존의 Entity 이름 앞에 Q를 붙인 QEntity가 생성된다.

QEntity는 QueryDSL에서 엔티티를 나타내는 클래스로,
QueryDSL을 사용하여 쿼리를 작성할 때 사용한다.

-- 여기서 내가 자주했던 실수
QEntity를 생성한 뒤 기존 Entity에 값을 추가할 경우,
다시 한번 Generate Sources and Update Folders실행해야한다.
자동으로 QEntity를 만들어주는게 아님을 항상 생각하자.


QueryDSL은 정적 타입 검사 및 코드 자동 완성을 제공하여
쿼리 작성 시 발생할 수 있는 오류를 사전에 방지하고, 쿼리 작성을 더 편리하게 만들어 준다.
예를 들어, @Query 어노테이션을 사용할 때

@Query("SELECT p.category, SUM(o.quantity) " +
       "FROM Product p " +
       "JOIN p.orders o " +
       "WHERE p.category = :category " +
       "GROUP BY p.catgory")
List<Orders> findBySalesSum(@Param("category") String category);

위 쿼리는 얼핏보면 오류가 없어보이지만
잘보면 Group By 절에 p.catgory , 오타가 있는 쿼리이다.
이처럼 @Query절은 유용하게 사용할 수 있지만
쿼리를 작성중에 개발자가 할 수 있는 실수를 캐치할 수 없는 단점 아닌 단점이 존재한다.
굉장히 유능한 시니어라면 실수도 안하겠지만 !

QueryDSL을 사용하여 쿼리를 작성하면 위 같은 오타를 IDE에서 발견해주기 때문에
나같은 주니어 개발자들이 오타를 걱정하지 않고 쿼리를 작성할 수 있게 도와준다.


@QueryProjections 어노테이션을 사용하여

생성자를 기준으로 DTO를 Entity와 매핑시키는게 가장 보편적인 방법이다.

반드시 생성자 기준으로 모든 파라미터가 구현되어야 하며,
하나라도 더 많거나 없다면 생성 자체가 되지 않는다.

DTO.class 를 따로 작성하여 @QueryProjections 어노테이션을 통해 생성자를 주입한다
@QueryProjections을 DTO.class 붙인 뒤 compile하면 DTO.class도 QClass가 생긴다!

// DTO.class
public class UserDTO {
    private String name;
    private int age;

    @QueryProjection // QueryProjection으로 생성자 주입
    public UserDTO(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

Service 단의 class에서 위 생성자를 기준으로 DTO와 매핑한다.

// service.class
JPAQueryFactory queryFactory = new JPAQueryFactory(em);
QUserEntity qUserEntity = QUserEntity.userEntity;

List<UserDTO> users = queryFactory
						.select(new QUserDto(qUserEntity.name, qUserEntity.age)
                        .from(qUserEntity)
                        .fetch();                                

이런식으로 @QueryProjections 어노테이션을 통해
Entity와 DTO를 매핑시키는 관계에서 QueryDSL을 사용할 수 있다.
오타를 방지하고, DTO의 형태도 사전에 정한대로 만들기 때문에 개발자의 실수를 방지할수있다.

profile
BackEnd & AWS Developer

0개의 댓글