Querydsl-SQL과 EntityQL

HeavyJ·2023년 5월 21일
0

자바/스프링부트

목록 보기
12/17

저는 JdbcTemplate을 이용하여 Bulk Insert를 해본 경험이 있습니다.
제 포스트를 보면 아시겠지만 이 Bulk Insert의 성능은 기존의 단건 삽입과 비교하면 비약적으로 성능을 향상시킬 수 있습니다.
Bulk Insert 포스트

Type-safe 한 Bulk 삽입 전략?

IDENTITY 생성 전략이 auto_increment일 경우에 JPA로 Bulk Insert가 안 된다는 점 때문에 JdbcTemplate을 선택했지만 문제점이 존재했습니다.

  • JdbcTemplate을 사용하면 네이티브 쿼리를 작성해야 하므로 TypeSafe하지 않습니다
  • Entity에서 컬럼의 추가 / 수정이 있을때마다 연관된 쿼리 문자열을 모두 찾아서 반영을 해야 합니다 -> 굉장히 번거로움

그렇다면, Type-safe하게 네이티브 쿼리를 작성할 수 있는 방법이 있을까요??

그 해결책이 될 Querydsl-SQL에 대해 알아보겠습니다.

Querydsl-SQL

Querydsl은 Type-safe하게 코드로 쿼리를 작성할 수 있는 장점을 가진 오픈소스입니다. 사람들이 일반적으로 사용하는 Querydsl은 Querydsl-JPA를 칭합니다.

하지만 Querydsl-SQL이라는 것도 존재합니다.

Querydsl-JPAQuerydsl-SQL의 차이는 변환 과정에 있습니다.

Querydsl-JPA는 JPAQueryFactory를 제공하는데 이 JPAQueryFactory를 통해 쿼리와 비슷한 형태의 로직을 작성할 수 있게 됩니다.
이 로직의 실행 과정은 다음과 같습니다.

Querydsl-JPA 변환 과정

  1. JPAQueryFactory로 질의 관련 로직 작성
  2. Querydsl이 1번의 로직을 JPQL로 변환
  3. JPQL은 DB에 맞는 Native SQL로 변환
  4. Native SQL이 실제 DB에서 실행

반면에 Querydsl-SQL에서 제공하는 SQLQueryFactory는 다른 과정을 거칩니다.

Querydsl-SQL 변환 과정

  1. SQLQueryFactory로 질의 관련 로직 작성
  2. 1번의 로직을 Native SQL로 변환
  3. Native SQL이 실제 DB에서 실행

즉, Querydsl-JPA는 코드 -> JPQL -> Native SQL순으로 변환해주고
Querydsl-SQL은 코드 -> Native SQL로 변환해줍니다.

그런데, 사람들은 왜 Querydsl-SQL을 잘 사용하지 않을까요??

그건 Querydsl-JPA에서 사용하는 Q클래스를 그대로 사용하지 못한다는 단점이 있습니다. SQLQuery를 위해 서 별도의 Q클래스를 따로 관리해야 하고 생성하는 방법이 Querydsl-JPA보다 훨씬 까다롭다는 점이 있습니다.

Q클래스 생성 과정이 복잡한데 먼저 실제 테이블을 Scan해야 하기 때문에 로컬 DB를 미리 실행하여 해당DB 접속정보를 등록해서 테이블을 scan할 수 있도록 설정이 되어야 한다는 점도 번거롭습니다.

EntityQL을 사용하여 이러한 번거로움을 해결할 수 있습니다.

EntityQL

EntityQL이란 JPA의 어노테이션을 기반으로 Querydsl-SQL Q클래스를 생성하는 역할을 해줍니다.

즉, 네이티브 쿼리를 사용할수 있는 Querydsl-SQL을 사용하려면 SQL용 Q클래스가 필요한데, 이 SQL Q클래스 생성을 테이블 스캔 방식이 아니라 JPA 어노테이션 기반으로 할 수 있는 중간 연결고리 역할을 하는 오픈소스입니다.

EntityQL 방식을 사용하여 테이블 스캔을 피하고 JPA처럼 어노테이션으로 Querdysl-SQL Q 클래스 생성이 가능해집니다.

다만, EntityQL에도 단점은 존재합니다.

  • Gradle 5 이상에서만 동작을 합니다
  • @Column - name 속성을 설정해야만 QClass의 필드가 선언됩니다.
    • @Enbedded를 지원하지 않기 때문에 복합적인 필드 구성이 불가능합니다.
  • @Table - name 속성을 설정해야만 테이블을 찾을 수 있습니다.
  • int, double, boolean과 같은 primitive type 필드의 사용이 불가능합니다.
profile
There are no two words in the English language more harmful than “good job”.

2개의 댓글

comment-user-thumbnail
2023년 5월 22일

Querydsl-JPA 와 Querydsl-SQL이 이런 차이가 있었군요!! 유용한 글 잘 읽었습니다!

1개의 답글