JPA - JPQL, QueryDSL에 대하여

죠랭이·2024년 4월 10일
0

Spring

목록 보기
2/2

회사에서 기술스택 중 하나인 JPA를 활용하면서 대부분 QueryDSL을 활용하고 있으나 때론 JPQL 혹은 Native Query를 작성할 필요가 있는 때가 있었다. 이 부분에 대해선 회사 기술 스택으로 활용하고 있기에 쓰긴 하지만 정확히 아는 것이 아니였어서 이 기회에 한번 자세히 들여다보았다.


일단, 본론의 주제로 들어가기에 앞서 우리가 흔히 사용하고 있는 JPA, Hibernate의 개념이 정확하게 무엇인지 파악할 필요가 있다. 이에 대하여 잘 설명한 기술 블로그 하나를 발견했는데 아래 hibernate 공식문서 그림으로 다 설명이 되었다.

우리가 흔히 사용하는 JPA는 Java Persistence API의 줄임말로 자바 언어와 영속성 프레임워크간의 API 명세라고 보면 된다. 이런 명세를 기반으로 구현한 것이 Hibernate Framework인 셈이다. Spring Boot 프레임워크를 활용하여 서버 개발을 하고 있는 어플리케이션에서는 Spring Data JPA 의존성을 프로젝트에 추가하여 개발할 것이다. 이는 ORM 프레임워크에서 제공하는 여러 컴포넌트와 기능들을 추상화하고 캡슐화하여 제공하는 모듈이라고 보면 된다. 우리가 실제 서비스 개발을 위해 프로그램을 작성할 때 EntityManager를 핸들링하게끔 작성하는가?Repository 인터페이스 선언 후 ORM 프레임워크와 연동을 위한 추가 코드를 작성하는가?' 를 생각해보면 어떤 의미인지 충분히 전달되었을 것으로 보인다.

여기서, JPQL과 QueryDSL 모두 객체 지향 쿼리다. 단순한 식별자로 Entity를 조회하는 것은 얼마든지 가능하나 특정 조건에 해당하는 데이터를 조회하려면 결국엔 데이터베이스와 SQL을 활용한 데이터 조회가 필요하다. 이때 활용하는 쿼리가 바로 JPQL 그리고 QueryDSL이다. 둘의 공통점으로는 추상화한 SQL이므로 특정 데이터베이스 제품에 종속적이지 않다. 또한, JPQL, QueryDSL 둘 다 테이블이 아닌 엔티티를 검색하는 객체 지향 언어이다.

그렇다면 둘의 차이는 과연 무엇일까? QueryDSL은 JPQL을 편하게 작성하도록 도와주는 빌더 클래스라고 보면 된다. 유사한 언어로 Criteria가 존재하는데 일반적으로 QueryDSL을 실무에서 많이 활용하고 있다.

일반적으로 JPQL 그대로 활용하게 된다면 오타와 같은 휴먼에러가 발생할 확률이 크다. 따라서, 컴파일 타임에 에러를 감지할 수 있는 코드 레벨에서 SQL 작성을 하고자 Criteria, QueryDSL을 활용한다. 이때, Criteria는 코드 작성 시 복잡하고 너무 장황하다는 단점이 존재. 이를 보완하고자 좀 더 단순하고 사용하기 쉬운 QueryDSL이 등장하였다.(여기서 필자는 사내 프로젝트를 진행하면서 QueryDSL을 실무에서 활용하나 오히려 지원하지 않는 기능(distinct 문법 등)으로 인하여 Native Query를 활용할 수밖에 없는 상황들이 종종 있었다.)

이런 차이에 유의하며 실무에서 활용하면서 다양한 문제들에 마주치며 경험에서 우러난 노하우를 습득하려고 꾸준히 나아가야겠다.

p.s. QueryDSL에서는 SubQuery도 지원한다. 필자가 회사에서 쿼리튜닝을 한 적이 있었는데 이때 활용한 기술이 바로 이 기술이다.

참고

  • 자바 ORM 표준 JPA 프로그래밍 - 김영한
profile
슈퍼 개발자를 목표로 하는 주니어

0개의 댓글