반응형
Spring Boot에서 JPA와 Querydsl 함께 사용하는 방법 (설정부터 실전 예제까지)
Spring Data JPA는 빠르게 CRUD 기능을 구현할 수 있는 장점이 있지만, 복잡한 동적 쿼리 작성에는 한계가 있습니다.
이때 실무에서 많이 활용하는 것이 Querydsl입니다. 정적 타입 기반으로 쿼리를 작성할 수 있어, 컴파일 타임 오류를 줄이고 유지보수가 편해집니다.
1. 왜 JPA + Querydsl 조합이 필요한가?
@Query또는 JPQL로는 복잡한 조건 처리에 한계가 있음- Querydsl은 정적 타입 기반으로 IDE 자동완성이 가능
- 복잡한 조건 쿼리, 동적 검색, 페이징 처리에 강력함
2. build.gradle.kts 설정 (Querydsl 의존성 추가)
dependencies {
implementation("com.querydsl:querydsl-jpa")
kapt("com.querydsl:querydsl-apt")
}
kapt {
arguments {
arg("querydsl.entityAccessors", "true")
}
}
sourceSets {
main {
java {
srcDirs("build/generated/querydsl")
}
}
}
Gradle 빌드 시 Q타입 클래스가 생성됩니다. 예: QMember
3. Entity 예제
@Entity
@Getter
public class Member {
@Id
@GeneratedValue
private Long id;
private String username;
private int age;
}
4. 사용자 정의 Repository 인터페이스
public interface MemberRepositoryCustom {
List<Member> search(String username, Integer age);
}
5. 사용자 정의 Repository 구현 클래스
@RequiredArgsConstructor
public class MemberRepositoryImpl implements MemberRepositoryCustom {
private final JPAQueryFactory queryFactory;
@Override
public List<Member> search(String username, Integer age) {
QMember m = QMember.member;
return queryFactory.selectFrom(m)
.where(
username != null ? m.username.eq(username) : null,
age != null ? m.age.eq(age) : null
)
.fetch();
}
}
6. Spring Data JpaRepository에서 상속
public interface MemberRepository extends JpaRepository<Member, Long>, MemberRepositoryCustom {
}
7. JPAQueryFactory Bean 등록
@Configuration
public class QuerydslConfig {
@PersistenceContext
private EntityManager em;
@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(em);
}
}
8. 테스트 예시
@Autowired
MemberRepository memberRepository;
@Test
void 검색테스트() {
List<Member> result = memberRepository.search("홍길동", 30);
assertThat(result).isNotEmpty();
}
9. 주의할 점
- Q클래스 생성 누락: Gradle 빌드 후
build/generated확인 - Spring Boot 3.x에서는 JPAQueryFactory 설정이 조금 다를 수 있음
- Querydsl의
null 무시 처리는 자동 적용되므로,where에 바로 조건 넣으면 됨
10. 실무 팁
- 검색 조건이 많아질 경우
BooleanBuilder또는Predicate활용 - DTO 매핑 시
Projections.constructor()또는fields()사용 - 단순 CRUD는 JPA, 복잡한 쿼리는 Querydsl로 역할을 분리하는 것이 좋음
맺음말
JPA만으로 모든 쿼리를 처리하려다 보면 한계에 부딪히게 됩니다.
Querydsl을 함께 사용하면 타입 안정성까지 갖춘 복잡한 쿼리를 손쉽게 작성할 수 있고, 생산성과 유지보수성 모두 잡을 수 있습니다.
오늘 소개한 구성은 실무에서도 가장 흔히 쓰이는 구조이니, 직접 적용해보시길 추천드립니다.
반응형
'웹개발 > Spring' 카테고리의 다른 글
| Spring Boot 403 Forbidden 에러 원인과 해결 방법 총정리 (1) | 2025.08.16 |
|---|---|
| Spring Boot 404 Not Found 에러 발생 원인과 해결 방법 총정리 (0) | 2025.08.15 |
| Spring Boot Logback 설정 완전 정리: 로그 포맷, 파일 분리, Rolling 설정까지 (3) | 2025.08.13 |
| Spring Boot에서 Multipart 파일 업로드 설정과 실전 예제 (JSP & REST 방식 모두) (2) | 2025.08.12 |
| Spring Boot에서 CORS 정책 오류 해결하기: 프론트 연동 시 필수 설정 가이드 (3) | 2025.08.11 |