본문 바로가기
JPA Study

JPQL과 QueryDSL

by xogns93 2024. 9. 24.

1. JPQL (Java Persistence Query Language)

JPQL은 JPA(Java Persistence API)에서 제공하는 객체 지향 쿼리 언어입니다. SQL과 유사하게 데이터베이스에서 데이터를 조회하고 조작할 수 있지만, JPQL은 데이터베이스 테이블이 아닌 엔티티 객체를 대상으로 작업합니다. 따라서 JPQL은 JPA 엔티티 객체의 속성이나 관계를 사용하여 쿼리를 작성하게 됩니다.

JPQL의 특징:

  • SQL과 유사: SQL처럼 SELECT, INSERT, UPDATE, DELETE 쿼리를 작성하지만, 데이터베이스 테이블 대신 JPA 엔티티 객체에 대해 쿼리를 실행합니다.
  • 데이터베이스 독립적: JPQL은 특정 데이터베이스에 종속되지 않으며, JPA 구현체가 데이터베이스에 맞는 SQL로 변환해 실행합니다.
  • 정적 쿼리: 쿼리 문자열이 고정되어 있고, 런타임에 특정 문자열만 바꿔서 실행됩니다.

JPQL 예시:

String jpql = "SELECT m FROM Member m WHERE m.age > :age";
TypedQuery<Member> query = em.createQuery(jpql, Member.class);
query.setParameter("age", 30);
List<Member> result = query.getResultList();
  • 이 쿼리는 Member 엔티티를 대상으로 age가 30보다 큰 회원을 조회하는 쿼리입니다.
  • m.ageMember 엔티티의 age 필드를 나타내며, 실제 데이터베이스 필드가 아닙니다.

2. QueryDSL

QueryDSL은 타입 안전한 쿼리를 제공하는 Java 기반의 도구입니다. JPQL과 비슷하게 객체 지향 쿼리를 작성하지만, Java 코드로 쿼리를 작성하므로 컴파일 시점에 문법 오류를 잡을 수 있습니다.

QueryDSL의 특징:

  • 타입 안전성: QueryDSL은 쿼리 작성 시 타입을 보장합니다. 잘못된 필드나 데이터 타입을 사용하면 컴파일 시점에서 오류가 발생합니다.
  • 동적 쿼리: QueryDSL은 동적 쿼리를 쉽게 작성할 수 있습니다. 조건문에 따라 쿼리 조건을 유동적으로 추가할 수 있습니다.
  • 코드 자동 생성: 엔티티 클래스를 기반으로 Q 클래스를 자동으로 생성하여 QueryDSL 쿼리를 작성할 수 있습니다.

QueryDSL 예시:

QMember member = QMember.member;
JPAQueryFactory queryFactory = new JPAQueryFactory(em);

List<Member> result = queryFactory
        .selectFrom(member)
        .where(member.age.gt(30))
        .fetch();
  • 이 코드는 Member 엔티티의 age가 30보다 큰 회원을 조회하는 쿼리입니다.
  • JPQL과 달리 쿼리 문자열이 아닌 Java 코드로 작성되어 있어 타입 안전성이 보장됩니다.

3. JPQL vs QueryDSL

구분 JPQL QueryDSL
쿼리 방식 문자열 기반 쿼리 언어 Java 코드 기반 쿼리 작성
타입 안전성 문자열이므로 컴파일 타임에 오류 확인 불가 타입 안전성 보장 (컴파일 시 오류 발견)
동적 쿼리 작성 복잡하고 오류 발생 가능성 높음 동적 쿼리 작성이 매우 간단함
가독성 문자열로 인해 긴 쿼리의 경우 가독성이 떨어짐 메서드 체이닝 방식으로 가독성이 좋음
SQL 독립성 JPQL을 SQL로 변환하는 과정이 필요 마찬가지로 SQL 독립적이며, Java 코드로 작성됨
성능 엔티티매니저 내부에서 JPQL을 파싱 후 실행 JPQL과 성능은 비슷하지만, 동적 쿼리에서 편리성 제공

4. 언제 JPQL을 사용하고 언제 QueryDSL을 사용해야 할까?

  • JPQL은 간단한 쿼리를 작성할 때 유용하고, 특정 상황에서는 더 직관적일 수 있습니다. 또한, 외부 라이브러리 의존성을 줄이고 JPA 기본 기능만으로도 충분한 경우 사용합니다.
  • QueryDSL타입 안전성과 동적 쿼리 작성이 중요한 상황에서 유리합니다. 특히, 쿼리가 복잡해지고 동적 조건이 많아지는 경우 QueryDSL이 훨씬 더 유용하며, 유지보수도 용이합니다.

결론적으로, 간단한 정적 쿼리는 JPQL을 사용하는 것이 간편하고, 동적이고 복잡한 쿼리는 QueryDSL을 사용하는 것이 효율적입니다.