Querydsl 과 JPQL 차이
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 을 사용하려면 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이 더 간편하다!)