Spring Boot와 QueryDSL 연동하기

김우경·2020년 11월 6일
1

JPA로는 복잡한 where문이나 join등 다양한 조회기능 사용하기 어렵다!

→ 정적 타입 지원하는 조회 프레임워크인 Querydsl을 사용해 봅시다

Maven 설정하기


의존성 추가하기

pom.xml

		<dependency>
			<groupId>com.querydsl</groupId>
			<artifactId>querydsl-apt</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>com.querydsl</groupId>
			<artifactId>querydsl-jpa</artifactId>
		</dependency>

플러그인 추가하기

pom.xml

<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.entityAccessors>true</querydsl.entityAccessors>
							</options>
						</configuration>
					</execution>
				</executions>
			</plugin>
  • Plugin 'com.mysema.maven:apt-maven-plugin:1.1.0' not found ???

Query Type 생성하기


위 플러그인에서

  • <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>

    : Entity 어노테이션이 추가된 도메인에 대해 <outputDirectory>에 설정한 경로에 query type을 생성해줌

rum maven compile 실행

-> 가끔 intellij 버전에 따라 run maven compile 대신 Maven-> Generate Sources and Update Folders

→ 우리가 pom.xml에 설정한 경로 target/generated-sources/java 에 @Entity 가 붙은 도메인에 대해 모두 쿼리타입이 생겼음!

Querydsl 사용하기


Java Config

: config모아놓은 패키지에 컨피그파일 추가하기

→ 이 설정까지만 완료하면 사용하는 방법은 간단합니당!

@Configuration
public class QuerydslConfiguration {

    @PersistenceContext
    private EntityManager entityManager;

    @Bean
    public JPAQueryFactory jpaQueryFactory() {
        return new JPAQueryFactory(entityManager);
    }

→ 이제 프로젝트 어디에서든 JPAQuery 주입받아 querydsl 사용 가능

Querydsl 기본 문법

: select * from application where user_no={{userNo}};

@RequiredArgsConstructor
@Repository
public class ApplicationQueryRepository {

    private final JPAQueryFactory query;

    public List<Application> findApplications(Long userNo){
        QApplication qApplication = QApplication.application;

        List <Application> fetched = query
                .select(qApplication.application)
                .from(qApplication.application)
                .where(qApplication.application.user.userNo.eq(userNo))
                .fetch();

        return fetched;
    }
}

→ 복잡한 쿼리에 대해서는 여기 참고하기

QueryDSL 사용법

구현하고자 하는 것

: user mypage에서 내가 쓴 지원서 중에 마감되지 않은 공고에 대한 지원서 조회하기

→sql

SELECT a.*
FROM application a, recriut r
WHERE a.user_no = {user_no} AND a.recruit_no = r.recruit_no AND r.closed_bit=0;

Repository 생성하기

: querydsl을 이용해 쿼리날릴 도메인 패키지에 repository 추가하기

상속/구현없이 간단하게 사용하기

package com.hanium.hfrecruit.domain.application;

import com.hanium.hfrecruit.domain.recruit.QRecruit;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import java.util.List;

@RequiredArgsConstructor
@Repository
public class ApplicationQueryRepository {

    private final JPAQueryFactory query;

    public List<Application> findActiveByRecruit(Long userNo){
        QApplication qApplication = QApplication.application;
        QRecruit qRecruit = QRecruit.recruit;

        List <Application> fetched = query
                .select(qApplication.application)
                .from(qApplication.application)
                .innerJoin(qRecruit.recruit)
                .on(qApplication.recruit.eq(qRecruit.recruit))
                .where(qApplication.application.user.userNo.eq(userNo),
                        qRecruit.recruit.closedBit.eq(0))
                .fetch();

        return fetched;
    }
}

컨트롤러에서 사용하기

@GetMapping("/mypage")
    public String mypage(@SessionAttribute("user") SessionUser sessionUser, Model model){
        User user = userRepository.findByEmail(sessionUser.getEmail()).orElseThrow(
                () -> new IllegalArgumentException("finding userNo Failed!")
        );
        Integer active = applicationQueryRepository.findActiveByRecruit(user.getUserNo())activeApplication.size();
        model.addAttribute("pageTitle", "마이페이지");
        model.addAttribute("user", user);
        model.addAttribute("activeApplication", active);
        return "mypage";
    }

완료!

profile
Hongik CE

0개의 댓글