본문 바로가기

Programming Language/Java

[JAVA] QueryDSL 이란?

QueryDSL 이란?


개요

  Spring Boot 프로젝트를 진행하던 도중, 직접 Query를 작성하게 되면서 사용하게 된 QueryDSL의 배경에 대하여 알아본다.

 

목차

 

소개

QueryDSL 이란?
QueryDSL이란, 정적 타입을 이용한 Query생성에 특화된 언어(Domain Specific Language)의 특징을 갖는 라이브러리이다. 

 

Spring 등장 이후, 개발자는 비즈니스 로직에만 집중하게 되면서 JPA를 사용하게 되었고, JPA로 구현할 수 없는 복잡한 Query는 JPQL을 사용하였다. 그럼에도 불구하고, QueryDSL이 나온 배경은 무엇일까?

 

QueryDSL의 등장배경 = JPQL의 한계

 

1) JPQL의 타입 안정성

  JPQL은 String 형태의 문자열로 작성하게 된다. 아래와 같이 코드가 작성하는 경우, String의 문자열로 값이 들어가있기 때문에, 잘못된 문법이 있다면 실제 서버가 띄워지고 로직이 수행되어야 에러를 발견할 수 있는 것이다.

String jpql = "Select t.id, avg(m.sales)" + "From Trainer t" + "Group By t.id";

 

2) 직관성

  함수를 작성할 때, 함수만을 보고 이 함수가 어떤 기능을 하는지 이해할 수 있는 것은 협업하는 과정에 있어서 중요하다. JPQL의 경우에는 이러한 직관성이 떨어진다.

public Member retrieveMemberInfo (String id) {
    String query = "Select * From Trainer";
    
    if (!StringUtils.isBlank(id))
      query += "Where userId = :id";

    TypedQuery<Member> jpqlQuery = em.createQuery(query,Member.class);

    if (!StringUtils.isBlank(id))
      jpqlQuery = jpqlQuery.setParameter("userId",id);
}

위의 코드는, id 값이 들어오면 Where 조건을 추가해주고, userId에 입력된 id값을 넣어 조회하는 Query문이다. 하지만 이러한 내용을 직관적으로 알기 어려움을 코드를 보면 알 수 있다. 이러한 한계점으로 인해, 개발자는 다시한번 비즈니스 로직에 집중하는 것이 아닌 Query를 짜는것에 시간을 보내야 했고 이를 보완하고자 Query 생성에 특화되어 JPQL을 생성해주는 QueryDSL이 등장하게 된 것이다.

 

그렇다면, Entity 데이터만 넘겨주면 JPQL을 생성해줄까?

 

정답은 아니다. JPQL은 JPA의 Entity 정보를 필요로 한다. 하지만, Entity를 그대로 사용하면 JPA에 종속되기 때문에 QueryDSL은 이를 예방하고자 Entity정보를 담고 있는 Q-type Class를 사용한다. Q-type Class는 QueryDSL의 플러그으로 컴파일하면 지정된 위치에 생성이 되고, JPQL을 생성하기 위해 필요한 데이터인 Q-type 객체를 QueryDSL 프로세스에 넘겨 사용한다.

 

그렇다면, Q-Type Class란 무엇일까?
QTypeClass는 QueryDSL을 사용할 때 생성되는 클래스이다. QTypeClass는 테이블 또는 엔티티를 사용하기 위해 QueryDSL에서 사용하는 메타 데이터라고 생각할 수 있다. QTypeClass는 테이블 또는 엔티티의 각 컬럼과 속성을 정의해두며, QueryDSL을 사용할 때 사용된다. 일반적으로 엔티티 Class의 이름앞에 Q를 붙혀서 사용되며, QTypeClass를 사용해 JAVA에서 타입 안정성을 유지하면서, 동적 SQL Query를 작성하게 한다. 동적으로 작성할 수 있게됨에 따라서, 코드 작성 및 유지보수를 더 용이하게 해주고 이를 통해 더 복잡한 Query를 안전하고 효율적으로 작성할 수 있게 된다.