Develop/Spring

[Spring] JPQL, QueryDSL : 기본 개념과 사용 예시

DevPi 2024. 9. 20. 09:21
반응형

Spring Boot와 JPA를 사용하는 개발 환경에서 데이터베이스와 상호작용할 때 JPQL과 QueryDSL은 중요한 역할을 합니다. 이 글에서는 JPQL과 QueryDSL의 기본 개념을 소개하고, 각 기술을 활용한 예시 코드를 제공하여 차이점을 이해할 수 있도록 설명합니다.


1. JPQL과 QueryDSL이란?

JPQL (Java Persistence Query Language)는 JPA에서 제공하는 쿼리 언어로, 객체를 대상으로 하는 쿼리를 작성할 수 있습니다. SQL과 유사하게 보이지만, SQL과는 달리 데이터베이스 테이블이 아닌 JPA 엔티티를 기반으로 작동합니다.

QueryDSL은 타입 안전성, 코드 자동 완성, 동적 쿼리 생성 등 다양한 장점을 제공하는 쿼리 빌더 라이브러리입니다. QueryDSL을 사용하면 Java 코드로 쿼리를 작성하여 런타임 에러를 최소화하고, 복잡한 동적 쿼리를 간편하게 생성할 수 있습니다.

 

2. JPQL 예시

아래는 Member 엔티티를 대상으로 JPQL을 사용하여 특정 조건의 데이터를 조회하는 예시입니다.

 

Member 엔티티 클래스

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Member {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private int age;

    // Getters, Setters, and Constructors
}

 

JPQL을 사용한 MemberRepository

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;

public interface MemberRepository extends JpaRepository<Member, Long> {

    // JPQL 쿼리를 사용하여 30세 이상 회원 조회
    @Query("SELECT m FROM Member m WHERE m.age > :age")
    List<Member> findMembersOlderThan(@Param("age") int age);
}

위의 코드는 JPQL을 사용하여 30세 이상인 회원을 조회하는 메서드를 정의한 것입니다.

 

3. QueryDSL 사용하기

QueryDSL은 JPQL보다 더 직관적이고 타입 안전한 쿼리를 작성할 수 있게 해줍니다. QueryDSL을 사용하려면 추가적인 설정과 빌드 설정이 필요합니다. 다음은 QueryDSL을 사용한 예시입니다.

 

QueryDSL 설정

먼저, QueryDSL을 사용하기 위해 Gradle 빌드 파일에 다음과 같은 의존성을 추가합니다.

dependencies {
    implementation 'com.querydsl:querydsl-jpa'
    annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jpa' // QueryDSL 코드 생성기
}

QueryDSL 코드 생성

QueryDSL을 사용하기 위해서는 엔티티에 대한 Q 클래스가 필요합니다. Q 클래스는 빌드 시 자동 생성되며, Member 엔티티에 대해 QMember 클래스를 생성합니다.

 

QueryDSL을 사용한 MemberRepository

import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.util.List;

import static com.example.demo.domain.QMember.member;

@Repository
@RequiredArgsConstructor
public class MemberQueryRepository {

    private final JPAQueryFactory queryFactory;

    // QueryDSL 쿼리를 사용하여 30세 이상 회원 조회
    public List<Member> findMembersOlderThan(int age) {
        return queryFactory
                .selectFrom(member)
                .where(member.age.gt(age))
                .fetch();
    }
}

 

QueryDSL 서비스에서의 사용 예시

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class MemberService {

    private final MemberQueryRepository memberQueryRepository;

    @Autowired
    public MemberService(MemberQueryRepository memberQueryRepository) {
        this.memberQueryRepository = memberQueryRepository;
    }

    public List<Member> getMembersOlderThan(int age) {
        return memberQueryRepository.findMembersOlderThan(age);
    }
}

 

4. JPQL vs. QueryDSL: 차이점

특징JPQLQueryDSL

특징 JPQL QueryDSL
쿼리 방식 문자열 기반의 쿼리 자바 코드 기반의 쿼리
타입 안전성 없음 (런타임 에러 발생 가능) 있음 (컴파일 타임에 오류 발견)
동적 쿼리 작성이 복잡함 동적 쿼리 작성이 쉽고 유연함
자동 완성 IDE에서 지원하지 않음 IDE에서 자동 완성 기능 지원
유지보수성 쿼리 복잡도가 높을수록 유지보수 어려움 코드 기반 작성으로 유지보수 용이

결론

JPQL과 QueryDSL 모두 Spring Boot와 JPA 환경에서 데이터베이스와 상호작용하는 데 매우 유용한 도구입니다. JPQL은 간단한 쿼리 작업에 적합하며, 문자열 기반으로 작성하므로 사용법이 비교적 쉽습니다. 그러나 QueryDSL은 타입 안전성을 보장하고, 동적 쿼리 작성이 훨씬 수월하여 복잡한 요구사항이 있는 프로젝트에서 특히 유리합니다.

JPQL은 익숙한 SQL 스타일의 쿼리를 작성하고자 할 때 사용하고, QueryDSL은 복잡한 쿼리와 타입 안전성을 요구하는 경우에 사용하는 것이 좋습니다. 프로젝트의 규모와 요구사항에 따라 두 방법을 적절히 선택하여 사용해 보세요.

반응형