카테고리 없음

JPA 환경에서 MyBatis? JPQL? QueryDSL?

땍땍 2026. 3. 7. 18:00

Springboot + JPA 환경에서 프로젝트를 개발하다 보면, 반드시 한 번쯤은 다수의 테이블을 Join 하여 특정 필요한 데이터만 조합해야 하는 경우가 반드시 찾아온다.

이때, JPA 를 100% 활용하기 위해서는 연관된 모든 Entity 를 조회한 뒤 Getter 를 통해 필요한 정보를 추출하고 조합하는 방식을 활용할 수 있지만 이는 사용하지 않는 데이터까지 DB 에서 가져와야 하기에 트래픽이 증가되면 증가될 수록 DB와 어플리케이션 단에 불필요한 부담을 발생시키게 된다.

물론, JPA 내부에서도 Projection 이라는 기능이 존재하여 이를 적절히 활용하여 해결할 수도 있겠지만 Join 이 복잡해지거나 동적으로 변하는 등 확장에 유연하게 대처하기 어려워 주로 아래 세 가지 선택지를 고려하게 된다.

 

1. JPA + MyBatis

MyBatis 는 기본적으로 SQL 를 어플리케이션에서 활용할 수 있도록 만들어진 매퍼이기 때문에 네이티브 쿼리를 작성하는데 익숙한 개발자라면 JPA 의 오버헤드 없이 DB 에 접근할 수 있다는 장점이 있다.

하지만, JPA 와 MyBatis 를 함께 활용하게 될 경우 JPA 와 MyBatis 라는 두 가지 영속성 접근 방식을 동시에 설정하고 유지보수 해야하기 때문에 복잡성이 크게 증가할 수 있다.

예를 들어, JPA 의 영속성 컨텍스트와 MyBatis 의 데이터가 동기화되지 않는 경우 JPA 로 수정한 데이터가 DB 에 플러시(반영) 되기 전에 MyBatis 가 과거 데이터를 조회해버리는 데이터 정합성 문제가 발생할 수 있다는 치명적인 문제 또한 존재한다.

 

2. @Query 어노테이션 활용 ( JPQL )

Spring Data JPA 에서는 기본적으로 @Query 어노테이션을 지원하여, 이를 활용하면 별도의 의존성 및 설정 추가 없이 Repository 인터페이스 내에서 직접 쿼리를 작성할 수 있다.

다만 이러한 JPQL 은 문자열로 작성하기 때문에 오타를 작성하는 등의 휴먼 오류가 발생하기 쉽고, 이러한 오류는 실제 해당 메소드를 호출하기 전까지 쿼리의 문법 오류를 발견할 수 없다는 큰 문제가 존재하여 테스트 코드가 강제되는 단점이 존재한다.

 

3. QueryDSL

QueryDSL 은 쿼리를 문자가 아닌 자바 코드로 작성할 수 있도록 지원해준다.

때문에 네이티브 쿼리와 활용 방법이 달라 초기 설정과 문법에 대한 학습 곡선이 존재하지만 아래와 같은 장점을 갖고 있다.

  • 쿼리를 자바 코드로 작성하는 만큼, 컴파일 시점에 오타나 타입 등의 오류를 탐지하여 휴먼 에러를 잡아낼 수 있다.
  • 자바의 메소드나 if 문 등을 활용해 어플리케이션 내에서 동적 쿼리 조작할 수 있다.
  • 기본적으로, JPA 영속성 컨텍스트의 관리를 받으며 Projections 기능을 활용해 이러한 영속성 컨텍스트를 우회하는 등의 상황에 따른 관리가 가능하다.