쇼핑몰 만들기 프로젝트 - QueryDsl을 사용해보자

yeom yaloo·2023년 7월 3일
0

쇼핑몰

목록 보기
13/19
post-thumbnail

[Querydsl 설정]

1. pom.xml 설정

</dependencies>
    <dependency>
        <groupId>com.querydsl</groupId>
        <artifactId>querydsl-apt</artifactId>
        <version>${querydsl.version}</version>
        <scope>provided</scope>
        <classifier>jakarta</classifier>
        </dependency>
        <dependency>
        <groupId>com.querydsl</groupId>
        <artifactId>querydsl-jpa</artifactId>
        <version>${querydsl.version}</version>
        <classifier>jakarta</classifier>
    </dependency>
</dependencies>
<build>
	<plugins>
		<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>
             
                <dependencies>
                    <dependency>
                        <groupId>com.querydsl</groupId>
                        <artifactId>querydsl-apt</artifactId>
                        <version>${querydsl.version}</version>
                    </dependency>
                </dependencies>
            </plugin>

2. querydsl 설정 전 버전 확인

  • 해당 프로젝트는 jdk 17 spring boot 3.0.x버전을 사용하고 있어서 javax와 관련된 이슈가 있었다.
  • 이를 해결하기 위해 찾아본 결과 spring boot 3버전 이상은 자바 API를 javax가 아닌 jakarta를 사용해야하는데 querydsl은 아직 javax를 사용하는 것으로 되어 있어 이 부분을 라이브러리를 추가할 때 진행해주어야 한다.
  • <classifier>jakarta</classifier>를 추가적으로 달아주어야 JPAQueryFactory 빈등록 시에 문제가 생기지 않는다.

3. configuration 작업

java를 사용한 설정 작업

package com.yaloostore.shop.config;

import com.querydsl.jpa.impl.JPAQueryFactory;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import jakarta.persistence.*;



@Configuration
public class QueryDslConfig {

    @PersistenceContext
    private EntityManager entityManager;

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

[Qtype class 생성]

1. 소스 루트 만들기

  • 위의 라이브러리 추가 작업을 진행하고 maven을 package해주면 아래와 같이 target 폴더에 Qtype class가 생성이 될것이다.
  • 이때 Qtype class를 사용해서 querydsl을 사용할 예정이기 때문에 해당 클래스가 생성된 폴더를 잘 살펴보자 (pom.xml에 작성한 querydsl outputDirectory 경로를 잘 살펴보자)

제대로 Qtype class가 생성된 경우

제대로 Qtype class가 생성되지 않은 경우

  • 소스 루트로 만들어주면 된다.
  • 소스 루트인데도 Qtype이 생성되지 않는다면 스프링부트와 querydsl의 javax, jakarta의 문제일 가능성이 높다 버전을 확인하도록 하자

잘 생성된 Qtype Class

  • 참고로 폴더 아이콘이 주황색이 아니고 member.entity처럼 회색이어야 한다. 주황색이라면 mark directory as에서 not excluded를 선택해서 제외하지 않도록 하자

2. 왜 Qtype class를 사용할까?

  • Qtype class는 querydsl 설정이 성공적으로 되면 @Entity가 붙은 클래스를 찾아서 자동으로 생성해준다.
  • Qtype class들은 querydsl을 사용해서 메소드 기반으로 쿼리를 작성할 때 우리가 만든 도메인 클래스(entity class)를 설명해주는 메타 데이터 역할을 하며 쿼리의 조건을 설정할 때 사용된다.

[Querydsl을 사용한 Repository]

1. 왜 querydsl을 사용할까?

2. 이제 Pagination을 곁들인 작업

QuerydslProductRepository

    @Override
    public Page<Product> queryFindAllProduct(Pageable pageable) {
        QProduct product = QProduct.product;

        List<Product> productList = factory.select(product)
                .from(product)
                .where(product.isExpose.isTrue()
                        .and(product.isSold.isTrue()
                                .and(product.rawPrice.gt(0))))
                .orderBy(product.productCreatedAt.desc())
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();

        JPAQuery<Long> countQuery = factory.select(product.count())
                .from(product)
                .where(product.isDeleted.isFalse()
                        .and(product.isSold.isTrue()
                        .and(product.rawPrice.gt(0))));

        return PageableExecutionUtils.getPage(productList, pageable, countQuery::fetchFirst);
    }
  • 해당 작업을 진행해두고 이제 해당 작업을 사용하는 곳에서 size, page 개수를 정해서 넘겨준다. (해당 작업을 본인은 front에서 restTemplate을 사용해서 작성한 서비스 로직에서 컨틀롤러에서 해당 작업을 넘겨받아서 진행했다.)

더 나아가서

  • querydsl과 qtype class jpaFactory를 사용한 API 작성은 이제 충분히 할수 있게 되었다고 생각한다. 그렇기 때문에 자주 변화하는 값을 계속 API로 불러오기보다는 Redis와 같이 가벼운 DB를 사용해서 구현해보고자 한다.
  • 대표적인 예로 실시간 랭킹같은 로직을 매번 API를 불러오는 작업이 아닌 Redis를 사용한 작업으로 진행해볼 예정
profile
즐겁고 괴로운 개발😎

0개의 댓글