Spring Boot

[무한댓글 게시판] 3. Service 작성시 QueryDSL 사용하기

어코링 2024. 2. 15. 12:02

https://eocoring.tistory.com/55

 

[무한댓글 게시판] 2. Entity / Repository / Service + QueryDSL 사용

https://eocoring.tistory.com/14 [무한댓글 게시판] 1. 테이블 설계(+테이블 생성) 간단한 게시판 프로젝트 만들기 주요기능 무한 댓글 좋아요 조회수 무한 댓글 무한댓글(댓글, 대댓글) 찾은 정보를 토대

eocoring.tistory.com

⭡여기서 Entity / Repository / Service 생성을 해주었다

Service를 생성해줬을시 지난 팀프로젝트에는 쿼리문을 JPQL을 사용해서 작성해주었는데,

이번 개인 프로젝트에서는 실무에서 자주 사용된다는 QueryDSL을 활용해보기로 하였다.

 

QueryDSL 은 한마디로 SQL, JPQL 등을 코드로 작성할 수 있도록 해주는 ✨빌더 오픈소스 프레임워크✨ 다.

사실, QueryDSL 이 JPA 에서만 사용하는 프레임워크로만 알 수도 있지만

공식 사이트 를 보면 JPA 뿐만 아니라 SQL, Mongodb, Lucenece 등 다양한 언어에 대해서 서비스를 제공한다.

이번엔 JPA 를 사용할 때 함께 많이 사용하는 QueryDSL JPA 에 대해서 알아보자

QueryDSL JPA

QueryDSL JPA 는

① SQL, JPQL 을 코드로 작성할 수 있도록 해주는 빌더 API 이고,
② Entity 클래스와 매핑되는 QClass 라는 객체를 사용해서 쿼리를 실행한다.

위에 설명을 읽다 보니깐 JPQL 이란 QClass 라는 키워드가 눈에 밝히는데 해당 단어들이 무엇을 의미하는 걸까 ?

QClass 란 ?

QueryDSL 은 컴파일 단계에서 엔티티를 기반으로 QClass 를 생성하는데 JPAAnnotationProcessor 가 컴파일 시점에 작동해서 @Entity 등등의 어노테이션을 찾아 해당 파일들을 분석해서 QClass 를 만든다.

QClass 는 Entity 와 형태가 똑같은 Static Class 이다.
QueryDSL 은 쿼리를 작성할 때 QClass 를 기반으로 쿼리를 실행한다.

JPQL 이란 ?

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

 

JPQL과 QueryDSL 차이

JPQL

  • Query문을 String으로 작성하기 때문에 문제가 발생하더라도 컴파일 시점에서 오류가 발생하지 않고 실행된다.
  • 실행 시점에서 오류를 발견할 수 있으며, 최악의 경우 사용자가 해당 SQL 쿼리를 발생하는 요청을 할 경우에 오류를 발견할 수도 있다.
  • 파라미터 바인딩을 직접 설정해 주어야 한다.

 

QueryDSL

  • Java 코드로 쿼리문을 작성하여 컴파일 시점에 오류를 발견할 수 있다.
  • 또한, IDE의 도움을 받아 타입 체크나 오타를 바로 발견하여 수정할 수 있다.
  • 파라미터 바인딩을 자동으로 처리해 주어 직접 설정할 필요가 없다.

QueryDSL 사용 Service

1. Maven 설정

의존성 추가

<dependency>
    <groupId>com.querydsl</groupId>
    <artifactId>querydsl-apt</artifactId>
</dependency>
<dependency>
    <groupId>com.querydsl</groupId>
    <artifactId>querydsl-jpa</artifactId>
</dependency>

 

플러그인 추가

 

<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>src/main/generated</outputDirectory>
                <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
            </configuration>
        </execution>
    </executions>
</plugin>

 

이렇게 하고 프로젝트 refresh하고 Maven Project Update 해준다.

 

 

그러면 이렇게 파일들이 추가된것을 확인해볼 수 있다.

이 파일들에서 다른 Service 들에서 import를 할 수 있는 것이다.

 

2. Java Config 설정

@Configuration
public class QueryDslConfig {

    @PersistenceContext
    private EntityManager entityManager;

    @Bean
    public JPAQueryFactory jpaQueryFactory() {
        return new JPAQueryFactory(entityManager);
    }

}

 

3. Service에서 QueryDSL 사용하기

private final JPAQueryFactory queryFactory;

JPAQueryFactory를 호출해와서 불변객체로 만들어준다.

위에서 플러그인 설치로 자동으로 설치가 된 

import static com.se.social.entity.QBoard.board;;

이걸로 객체를 불러와줘서 테이블을 사용할수 있게되었다.

// selectList
	@Override
	public List<Board> selectList() {
		return queryFactory
				.selectFrom(board)
				.where(board.board_delyn.eq('N'))
				.orderBy(board.board_id.desc())
				.fetch();
	}

이렇게 간단하게 board 테이블의 board_delyn의 옵션이 default가 N인 튜플만 반환하게 하고(eq('N'))),

최근 게시물이 제일 상단부터 배치하기 위해 board 테이블의 board_id를 오름차순으로 반환하게하는 orderby문을 작성하였다.

QueryDSL을 써보고 JQPL보다 쓰는 방법이 간편하고, 가독성이 좋다는 것을 알게 되었다. 이후 자주 쓰게 될 것같다.