ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [무한댓글 게시판] 3. Service 작성시 QueryDSL 사용하기
    Spring Boot 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보다 쓰는 방법이 간편하고, 가독성이 좋다는 것을 알게 되었다. 이후 자주 쓰게 될 것같다.

     

Designed by Tistory.