본문 바로가기
Framekwork/SPRING

[스프링부트] QueryDSL 정리

by 아이엠제니 2024. 2. 29.

 

 


 

 

 

이전에 스프링부트 실습을 할 때는, 테이블 간의 JOIN이 따로 없었던 것 같다.

그래서 테이블 간의 JOIN에 대해서는 생각도 할 수 없었다.

그리고 이번에는 서버 프로젝트가 아닌 스프링부트를 활용하는 프로젝트에 들어가게 되었는데!

조인해야 하는 테이블들이 많았다.

뭔가 간단한 JOIN도 쉽지 않았다.

그나마 다행인 것은 같이 프로젝트를 하는 분에게 많이 여쭤볼 수 있다는 것이다.

물론 최대한 스스로 해본 후에 여쭤본다.

답을 알려주신다기보다, 방법에 대해 알려주신다.

스스로 해볼 수 있도록 많이 독려해 주시는 편. (감사합니다..)

 

 

아무튼 그래서 이번에 처음 사용해 보게 된 QueryDSL.

당연히 이론을 베이스로 가져가는 게 좋지만?

프로젝트를 하면서 느꼈는데, 확실히 뭔가 상황이 발생해서 얻는 게 더 많은 것 같다...

당연히 공부도 해야 하지만, 그 간절함이 다른 것 같다.

프로젝트는 정말 실전이다 보니, 민폐끼치는 것은 당연히 안 된다는 마음가짐과...

내가 맡은 일 정도는 완벽하게(당연히 지금 상황에서는 그럴 수 없겠지만...) 하고 싶은 마음 적인 마음이랄까.

아무튼 QueryDSL 을 프로젝트 끝날 때까지는 계속 사용하게 될 것 같아서 간단하게 정리를 하고자 한다.

티스토리에 적어두면, 나중에 찾아서 보게 된다.

 

 

 

QueryDSL
  • 자바 언어를 사용하여 데이터베이스 쿼리를 작성하기 위한 도구
  • JPA(Java Persistence API)나 Hibernate와 같은 ORM(Object-Relational Mapping) 프레임워크와 함께 사용되며, 데이터베이스와의 상호 작용을 더 쉽게 만들어줌

 

 

 

springboot: 2.7.17
java: 11

 

 

 

 

1. 의존성 추가

        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
<!--            <version>5.0.0</version>-->
        </dependency>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-apt</artifactId>
<!--            <version>5.0.0</version>-->
        </dependency>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-sql</artifactId>
<!--            <version>5.0.0</version>-->
        </dependency>

실제 프로젝트는 이렇게 설정이 되어 있었다.

버전이 주석 처리 되어 있는데?

버전을 적용하면, 컴파일이나, 인스톨 시 에러가 나는 경우가 있다.

그래서 버전이 주석 처리 되어있는 것 같다. (내가 주석 처리 한 건 아니라서...)

 

 

 

2. 플러그인 설정

            <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.1.3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/annotations</outputDirectory>
                            <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

 

 

 

 

3. JavaConfig 클래스 생성

package io.config;

import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Configuration
public class JpaConfig {

    @PersistenceContext
    private EntityManager entityManager;

    @Bean
    JPAQueryFactory jpaQueryFactory() {
        return new JPAQueryFactory(entityManager);
    }
}
  • '@Configuration' 애노테이션
    • Spring의 Java 기반 설정 클래스
  • '@PersistenceContext' 애노테이션
    • JPA에서 엔티티 매니저를 주입받기 위한 애노테이션
    • 스프링은 이를 사용하여 EntitiyManager를 주입함
      • EntityManager: 인터페이스. 데이터베이스와의 상호 작용을 담당
      • JPAQueryFactory를 생성할 때 EntityManager를 주입하는 이유는 QueryDSL이 JPA 엔터티와 함께 작동하도록 하기 위해서임
  • 'EntityManager entityManager' 필드
    • JPA의 'EntityManager'를 주입받기 위한 필드
  • '@Bean' 애노테이션
    • 빈을 생성하는 메서드
    • 메서드의 반환 값인 'JPAQueryFactory' 객체가 스프링 컨테이너에 빈으로 등록됨
  • 'JPAQueryFactory jpaQueryFactory()'
    • 'JPAQueryFactory' 빈을 생성하는 메서드
    • QueryDsl을 사용하기 위한 핵심 클래스로, JPA에 특화된 QueryDSL 쿼리 빌더를 생성하는 역할을 함
    • 생성자로 'EntityManager'를 전달하여 'JPAQueryFactory'를 생성함
  • 이렇게 빈으로 등록하면 다른 컴포넌트에서 '@Autowired' 등을 사용해서 'JPAQueryFactory'를 주입받아 사용할 수 있음

 

처음에 했을 reposity 클래스에서

 private final JPAQueryFactory queryFactory;

    @Autowired
    public UserService(EntityManager entityManager) {
        this.queryFactory = new JPAQueryFactory(entityManager);
    }

'JPAQueryFactory'를 @Autowired 애토네이션을 통해 주입받았는데!

queryFactory에 밑줄 오류가 났다.

그래서 config에 따로 'JpaConfig'를 생성한 후, 다시 보니!

빨간 밑줄이 없어졌다.

 

 

 

4. QueryDSL

# Entity 및 QueryDSL Entity Path 설정
QUser qUser = QUser.user;

# 쿼리 팩토리 생성
JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);

# SELECT문 작성
List<User> users = queryFactory
    .selectFrom(qUser)
    .fetch();

 

간단하게는 대략 위처럼 작성한다.

차후에 실제 내가 간단하게 만들어본 후에 결과물을 올려볼 수 있도록 해야겠다.

 

 

처음에 다른 분이 작성하는 코드를 보고, Q가 들어간 게 뭔가 싶었는데?

Q클래스는 QueryDSL이 엔터티를 기반으로 생성하는 클래스라고 한다.

이렇게 간단하게 SELECT 문을 작성하는 거라면 괜찮을 것 같은데,,,

 

한 테이블에서 3번의 join과 join의 join을 해야 하는 상황이 곧 나에게 닥칠 미래라서...

연휴 동안 QueryDSL과 JPA에 대한 학습을 해야 할 것 같다.

사실 오늘 join의 join을 하는 데에도 정말...

몇 시간을 헤맸다.

A테이블과 B테이블의 관계와 조건을 생각하며 이렇게 저렇게 했는데도 아웃풋이 좋지 않았음...

이거 해결 못하면 집에 못 간다고 생각하면서도, 속으로는 (할 수 있다..)를 외쳤더니..!

다행히 해결하고 퇴근했다.

절망의 순간들이 찾아 오지만, 할 수 있다고 생각하니 하게 되는 듯..

하자.

 

 

 

300x250