1 minute read

jpa 를 도와주는 프로그램은 여러 개가 있습니다 그 중에 JPQL 과 Querydsl 이 있는데 그 둘의 차이점이 뭔 지, 예제를 보여주며 설명해보겠습니다.

JPQL

JPQL 은 JPA entity를 토대로 EntityManger 를 통해 string query 를 직접 쳐서 작성합니다. 직접 사용해보니 mybatis 와 비슷한 느낌이 납니다.

@Test
void startJPQL() {
    Member findMember = em.createQuery("select m from Member m" +
            " where m.username = :username", Member.class)
            .setParameter("username", "hachi")
            .getSingleResult();

    Assertions.assertThat(findMember.getUsername()).isEqualTo("hachi");
}

Querydsl

QueryDSL 은 함수 체이닝을 통해 쿼리를 작성합니다. Querydsl 의 더 자세한 얘기는

Querydsl 설정하기

여기에 있습니다.

Querydsl 의 예제입니다. 윗 글에 더 자세한 얘기들이 있지만 여기서 간략하게 설명하자면 Querydsl 을 사용하려면 maven complie 을 해서 entitiy를 따로 Querydsl 입맛에 맞게 한번 감싼 클래스가 자동으로 생성됩니다. (ex : QMember, QItem)

@Test
void startQuerydsl() {
    JPAQueryFactory queryFactory = new JPAQueryFactory(em);
    QMember m = new QMember("m");

    Member findMember = queryFactory
            .select(m)
            .from(m)
            .where(m.username.eq("hachi"))
            .fetchOne();

    Assertions.assertThat(findMember.getUsername()).isEqualTo("hachi");
}

둘의 차이점

둘의 차이점은 코드를 보기만 해도 알 수 있습니다.

JPQL 은 string query 로 직접 쿼리를 짜고, Querydsl 은 함수 체이닝으로 자동으로 쿼리를 작성하게 됩니다. 사실 이것 말고 차이가 없다면 사람 특성상 입맛에 맞는 거 찾아서 사용하면 되겠지만 그게 아닙니다!

JPQL 은 쿼리에 오류가 생겨도 오류를 잡지 못합니다. JPQL 의 쿼리는 순 string 이기 때문에 실행 시점에서 직접 사용했을 때 발견할 수 있습니다.

Member findMember = em.createQuery("slect m from Member m" +
        "where m.username = :username", Member.class)
..생략..
}

이 쿼리엔 많은 문제점들이 있습니다. 실행은 되겠지만..ㅎㅎ 원하는 결과가 나오질 않습니다.

Querydsl 은 함수 체이닝이기 때문에 오류가 생기면 컴파일 시점에서 오류를 잡을 수 있습니다. java code 이기 때문에 실행시켜봐도 실행이 되지않습니다.

Member findMember = queryFactory
        .slect(m)
        .from(m)
        .where(m.username.eq("hachi"))
        .fetchOne();

select() 부분을 보시면 컴파일 시점부터 오류가 생겨서 빨간줄이 그어지고, 실행조차 안됩니다.

사진

Querydsl 은 실행 전까지의 과정은 귀찮겠지만 JPQL 보다 압도적으로 큰 장점을 가지고있는 건 바로 이 점 같습니다.

JPQL 은 where 절을 사용할 때 setparameter 로 바인딩을 직접 시킵니다.

Member findMember = em.createQuery("select m from Member m" +
            " where m.username = :username", Member.class)
            .setParameter("username", "hachi")

하지만 Querydsl 은 eq() 을 통해 짧고 간단하게 바인딩 시켜줍니다.

.where(m.username.eq("hachi"))

결론

  • JPQL 은 오류가 발생해도 잘 모른다.
  • Querydsl 은 컴파일 시점에서 오류가 잡힌다
  • where 절 바인딩의 방식이 매우 다르다 (Querydsl이 더 간편하다!)

모든 코드를 한 눈에 보고싶다면 여기로 와주세요

Categories:

Updated: