JPA로는 복잡한 where문이나 join등 다양한 조회기능 사용하기 어렵다!
→ 정적 타입 지원하는 조회 프레임워크인 Querydsl을 사용해 봅시다
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>
위 플러그인에서
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
: Entity 어노테이션이 추가된 도메인에 대해 <outputDirectory>
에 설정한 경로에 query type을 생성해줌
-> 가끔 intellij 버전에 따라 run maven compile 대신 Maven-> Generate Sources and Update Folders
→ 우리가 pom.xml에 설정한 경로 target/generated-sources/java
에 @Entity 가 붙은 도메인에 대해 모두 쿼리타입이 생겼음!
: config모아놓은 패키지에 컨피그파일 추가하기
→ 이 설정까지만 완료하면 사용하는 방법은 간단합니당!
@Configuration
public class QuerydslConfiguration {
@PersistenceContext
private EntityManager entityManager;
@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
→ 이제 프로젝트 어디에서든 JPAQuery 주입받아 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;
}
}
→ 복잡한 쿼리에 대해서는 여기 참고하기
: 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;
: 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";
}