몬그로이

QueryDSL 본문

Organizing Docs/Spring Docs

QueryDSL

Mon Groy 2024. 6. 30. 20:00

QueryDSL 이란

Domain Specific Language 를 사용하여 SQL 을 생성하는 도구

Hibernate의 @Query 어노테이션을 사용하여 JPQL을 정의하거나,

JDBC Template을 사용하여 직접 SQL 쿼리를 작성하는 대신 사용

 

타입 안정성

Java 언어의 타입 시스템을 활용하므로  코드를 컴파일할 때 타입 안정성을 보장

SQL 문법 오류를 미리 잡을 수 있음

 

객체지향적인 쿼리

Java 언어의 문법을 사용하여 데이터베이스 쿼리를 표현하므로

개발자가 직관적으로 이해하고 유지보수할 수 있음

 

동적 쿼리 작성의 용이성

풍부한 문법과 메서드 체이닝을 통해 동적 쿼리를 간편하게 작성할 수 있습니다. 필요에 따라 조건을 추가하거나 조합할 수 있어 복잡한 쿼리도 효율적으로 처리할 수 있습니다.

 

다양한 데이터베이스 지원

각 데이터베이스에 맞는 SQL을 생성할 수 있습니다. 이는 개발자가 특정 데이터베이스의 기능을 최대한 활용할 수 있음을 의미

 


QueryDSL 을 사용하기 위해 필요한 것 = Q클래스

 

쿼리 전용 클래스(Query-specific class) 란?

쿼리 전용 클래스로, Entity 의 매핑 정보를 활용하도록 제공해주는 클래스로

엔티티 클래스와는 달리 데이터베이스의 특정 측면에 집중하며,

특정 쿼리 작업을 처리하기 위한 구체적인 메서드와 로직을 제공하는 클래스

 

쿼리 작성 및 실행을 위한 메서드 제공: 엔티티 클래스와 달리 특정 쿼리를 실행하기 위한 메서드들이 포함되어 있습니다. 이 클래스는 데이터베이스 쿼리를 생성하고 실행하는 데 필요한 모든 로직을 포함할 수 있습니다.

 

엔티티와의 관계 없음: 엔티티 클래스와 달리 특정 데이터베이스 테이블이나 일부 엔티티와 직접적인 관계가 없을 수 있습니다. 즉, 이 클래스는 데이터베이스 레이어에 집중하며, 데이터베이스의 테이블 구조와 관련된 작업을 처리합니다.

 

쿼리의 매핑 정보 활용: ORM 프레임워크에서는 엔티티 클래스를 이용하여 쿼리를 작성하는 것이 일반적이지만, 쿼리 전용 클래스에서는 필요에 따라 엔티티의 매핑 정보를 활용할 수 있습니다. 예를 들어, 엔티티 클래스의 필드 이름이나 데이터베이스 컬럼과의 매핑 정보를 참조하여 쿼리를 동적으로 생성할 수 있습니다.

 

쿼리 빌더와의 통합: 쿼리 빌더 라이브러리는 쿼리를 프로그래밍 방식으로 동적으로 생성하고 조작할 수 있는 도구입니다. 쿼리 전용 클래스는 이러한 쿼리 빌더를 활용하여 복잡한 쿼리 로직을 구현하는 데 유용하게 사용될 수 있습니다.


Q클래스를 만들기 위해 필요한 것 = JPAQueryFactory

 

EntityManager를 통해 Entity에 대한 쿼리를 생성하고 실행할 수 있는 팩토리 클래스로,

Q클래스를 사용하여 (문자열이 아닌) QueryDSL(객체 또는 함수)로 쿼리를 작성하고 실행하게 해주는 환경을 제공

 

EntityManager를 생성자로 전달받아 초기화되며, 이를 통해 JPA의 엔티티 클래스들과 연동하여 쿼리 작성을 지원

동적 쿼리도 쉽게 작성할 수 있도록 도움 ( 조건에 따라 WHERE 절을 추가하거나, JOIN을 수행하거나, 정렬 및 페이징 설정 가능)

JPAQueryFactory는 JPA의 EntityManager와 함께 사용되므로, JPA의 트랜잭션 내에서 동작함

>> JPA 가 지원하는 여러 기능과 함께 사용 가능함

 

사용 예시

@PersistenceContext

EntityManager em;

 

public List<User> selectUserByUsernameAndPassword(String username, String password){

      JPAQueryFactory jqf = new JPAQueryFactory(em);

       QUser user = QUser.user;

 

       List<Person> userList = jpf

       .selectFrom(user)

       .where(person.username.eq(username)

       .and(person.password.eq(password))

       .fetch();

 

       return userList;

}

 


JPAQueryFactory를 사용하기 위한 사전 작업

JPAQueryFactory 에 entityManager 를 주입해서 Bean 으로 등록

 

// configuration 패키지안에 추가

 

@Configuration

public class JPAConfiguration {

 

       @PersistenceContext

        private EntityManager entityManager;

 

       @Bean

        public JPAQueryFactory jpaQueryFactory() { //jpaQueryFactory 를 Bean 으로 등록 -> Spring 에서 관리하게 함

                  return new JPAQueryFactory(entityManager);

        }

}

*Spring 에서 jpaQueryFactory 를 관리할 수 있게 되었으므로

다른 클래스에서 JPAQueryFactory 를 주입받으면 QueryDSL 기능을 사용할 수 있게 됨

 

JPAQueryFactory 주입받아 사용하는 예시

public class MemberRepository {

        private final JPAQueryFactory queryFactory; //JPAQueryFactory 주입

 

        public MemberRepository(EntityManager entityManager) { 

                this.queryFactory = new JPAQueryFactory(entityManager);

        } //JPAQueryFactory 초기화 //또는 @RequiredArgsConstructor 사용

       

        public void createQClass() {

                QMember qMember = QMember.member; // Q클래스 생성

       //이후 QMember를 이용하여 QueryDSL을 활용해 동적 쿼리 작성 가능

        *Q 클래스가 필수인 건 아님 - 아래 접은글 참고

        }

}

더보기

Q클래스가 필수인 것은 아님

 

JPAqueryFactory는 querydsl 의 일부로,

Q클래스를 사용하지 않고도 동적 쿼리를 작성하고 실행할 수 있는 인터페이스를 제공함

 

Q클래스를 사용하는 방식은 IDE와의 통합이나 타입 안정성 등의 이점을 가질 수 있기 때문에

프로젝트의 복잡성이나 요구사항에 따라 Q클래스 사용여부를 결정하면