[SpringBoot] QueryDSL JPA 사용 이유 생각해보기

유아 Yooa·2023년 8월 27일
4

Spring

목록 보기
17/18
post-thumbnail

QueryDSL이란?

Querydsl was born out of the need to maintain HQL queries in a typesafe way. Incremental construction of HQL queries requires String concatenation and results in hard to read code. (출처-공식문서)

  • QueryDSL은 HQL(Hibernate Query Language)의 쿼리를 타입에 안전하게 생성 및 관리해주는 프레임워크
  • 즉, SQL, JPQL 등을 코드로 작성할 수 있도록 해주는 빌더 오픈소스 프레임워크이다.

HQL for Hibernate was the first target language for Querydsl, but nowadays it supports JPA, JDO, JDBC, Lucene, Hibernate Search, MongoDB, Collections and RDFBean as backends. (출처-공식문서)

  • JPA 뿐 아니라 SQL, MongoDB, Lucenece 등 다양한 언어에 대해서 서비스를 제공한다.

Type safety

Type safety is the core principle of Querydsl. Queries are constructed based on generated query types that reflect the properties of your domain types. Also function/method invocations are constructed in a fully type-safe manner. (출처-공식문서)

  • 일반적으로 SQL은 type check가 불가능하고 실행되기 전까지 작동 여부를 확인하기가 어렵다.
  • QueryDSL은 Java로 type safety하게 개발할 수 있도록 제공해주는 프레임워크라는 것👀

QueryDSL을 사용하는 이유

JPQL의 문제

JPA에서 지원하는 다양한 쿼리 방법 중 가장 단순한 조회 방법으로, SQL의 경우에는 DB 테이블을 대상으로 쿼리를 질의하지만, JPQL은 엔티티 객체를 대상으로 쿼리를 질의한다.

String username = "java";
String jpql = "select m from Member m where m.username = :username";

List<Member> result = em.createQuery(query, Member.class).getResultList();
  • 쿼리를 여전히 문자열로 입력하므로 오타가 발생하면 관리하기가 어렵고 type-check가 불가능하다.
  • 이러한 이유로 컴파일 단계에서는 오류를 발생할 수 없어 런타임에서 해당 쿼리가 실행되어야 오류를 발견할 수 있다.
    • 테스트 코드를 작성하면 불안을 덜 수는 있지만, 실제 프로그램을 운영하면서 오류가 발생할 수 있다는 부담이 너무 커진다.

✏️ 공식 문서에서 발견한 QueryDSL의 핵심은 유형 안전성의 결여정적 쿼리 검사의 부재를 해결해준다는 것.

  • QueryDSL은 쿼리를 코드를 통해 작성하기 때문에 오타가 발생할 확률이 줄고, 객체 지향적으로 개발할 수 있다.
  • 컴파일 단계에서도 오류를 빠르게 발견할 수 있다.
    자바 백엔드 기술은 Spring Boot와 Spring Data JPA를 함께 사용한다. 하지만, 복잡한 쿼리, 동적 쿼리를 구현하는 데 있어 한계가 있고 이를 해결해준다.
String username = "java";

List<Member> result = queryFactory
        .select(member)
        .from(member)
        .where(usernameEq(username))
        .fetch();

QClass

  • 기본적으로 QueryDSL을 사용할 때 QClass라는 자식이 생성된다.
  • QueryDSL은 컴파일 단계에서 엔티티를 기반으로 QClass를 생성하는데 JPAAnnotationProcessor가 컴파일 시점에 작동해서 @Entity 등의 특정 어노테이션을 찾아 해당 파일들을 분석해서 QClass를 만든다.

APT(Annotation Processor Tool)

  • 어노테이션이 있는 기존 코드를 바탕으로 새로운 코드와 새로운 파일들을 만들 수 있고, 이들을 이용한 클래스에서 컴파일하는 기능을 지원한다.
  • 쉬운 예시로 Lombok의 @Getter@Setter가 있다.
    • APT가 컴파일 시점에 해당 어노테이션 기준으로 getter와 setter를 만들어주는 것 처럼.
  • QClass는 엔티티 메타 정보를 담고 있는 클래스로, QClass를 기반으로 type safety하게 쿼리를 작성할 수 있게 된다.
  • 엔티티 클래스와 형태가 같은 Static Class로 엔티티의 속성을 나타내고 있다. 엔티티 속성을 직접 참조하고 조합해 쿼리를 구성할 수 있다.

왜 엔티티 대신 QClass를 사용할까?

  • 엔티티 속성을 static 방식으로 표현하므로 IDE의 자동 완성 기능을 활용할 수 있고, 속성 이름을 직접 기억할 필요가 없다는 장점이 있다.
  • 쿼리를 작성하는 동안 컴파일러가 타입을 확인할 수 있기 때문에 런타임에 발생할 수 있는 타입 관련 오류를 사전에 방지할 수 있다.

정리해보면..🤔

  • 엔티티 클래스는 데이터베이스와 매핑되는 자바 클래스로 데이터베이스 스키마를 표현하고 데이터베이스와의 연동을 위해 사용되며,
  • QClass는 타입 안전한 쿼리 작성을 위해 엔티티 클래스의 정보를 활용한다고 생각하면 될 것 같다.

참고

profile
기록이 주는 즐거움

0개의 댓글