ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 🍀 MongoDB - QueryDsl with Spring
    🌱 spring 2023. 5. 30. 14:44

    프로젝트를 진행하는 도중 여러 조건을 통해 mongoDB에 있는 데이터를 조회하는 기능이 필요했다.

    이에 따라 복잡한 쿼리를 쉽게 작성하기 위해 QueryDsl을 적용해보고자 했다.

    📌 QueryDSL


    💡 QueryDSL은 정적 타입을 이용해 SQL과 같은 쿼리를 생성할 수 있도록 해주는 오픈소스 프레임워크

     

    • JPQL을 Java 코드로 작성할 수 있도록 하는 라이브러리

     

    🧑‍💻 Query DSL 설정

    📖 build.gradle

     

    plugins {
    	id "com.ewerk.gradle.plugins.querydsl" version '1.0.10'
    }
    
    ...
    
    dependencies {
      ...
    	implementation group: 'com.querydsl', name: 'querydsl-mongodb', version: "${querydsl_version}"
    	annotationProcessor "com.querydsl:querydsl-apt:${querydsl_version}"
      ...
    }
    
    // Qtype 생성 경로
    def querydslDir = "$buildDir/generated/querydsl"
    querydsl {
    	springDataMongo = true
    //	jpa = true
    	querydslSourcesDir = querydslDir
    }
    sourceSets {
    	main.java.srcDir querydslDir
    }
    configurations {
    	querydsl.extendsFrom compileClasspath
    }
    compileQuerydsl {
    	options.annotationProcessorPath = configurations.querydsl
    }
    

     

    📍 @QueryEntity, Q Class

    QueryDSL을 적용하고자 하는 Document에 @QueryEntity 어노테이션을 정의

     

    @QueryEntity
    @Document(collection = "pet")
    @Getter
    @Builder
    @NoArgsConstructor(access = AccessLevel.PROTECTED)
    @AllArgsConstructor
    public class Pet implements Serializable {
    
      @Id
      private String id;

     

     

    생성된 Q Class

    /**
     * QPetData is a Querydsl query type for Pet
     */
    @Generated("com.querydsl.codegen.DefaultEntitySerializer")
    public class QPet extends EntityPathBase<Pet> {
    
        private static final long serialVersionUID = -2081981488L;
    
        public static final QPet petData = new QPet("pet");

     

    📍 QueryDSL을 통해 동적 쿼리 생성

    PetRepository

    public interface PetQueryRepository extends MongoRepository<Pet, String>,
        QuerydslPredicateExecutor<Pet>,
        UserQueryRepositoryWrapper {
    
      ...
    }

     

    UserQueryRepositoryWrapper

    • 복잡한 쿼리를 위한 interface
    public interface UserQueryRepositoryWrapper {
    
      Page<PetData> findAllSortedBy(SortType sortType, Pageable pageable);
    
    }

     

    PetRepositoryImpl

    public class PetQueryRepositoryImpl extends QuerydslRepositorySupport implements UserQueryRepositoryWrapper{
    
      private static final QPet petCollection = QPet.pet;
    
      public PetQueryRepositoryImpl(MongoOperations operations) {
        super(operations);
      }
    
      @Override
      public Page<Pet> findAllSortedBy(SortType sortType, Pageable pageable) {
    
        SpringDataMongodbQuery<PetData> query = from(petCollection)
            .orderBy(getSortExpression(sortType));
    
        long totalCount = query.fetchCount();
    
        query.limit(pageable.getPageSize()).offset(pageable.getOffset());
    
        List<Pet> results = query.fetch();
    
        return new PageImpl<>(results, pageable, totalCount);
      }

     

    ⭐️ QueryDSL 장점

    📖 Type-Safe

    QueryDSL로 쿼리를 작성할 때, QType을 이용해 쿼리를 Type-Safe하게 작성할 수 있다.

    ❗ 컴파일 시점에 타입 체크가 가능하다.

    • 오타 또는 존재하지 않는 컬럼명을 사용할 경우 확인 가능하다.

    📖 직관적으로 동적쿼리를 확인할 수 있다.

     

    참고자료

    https://www.baeldung.com/queries-in-spring-data-mongodb

    https://www.baeldung.com/querydsl-with-jpa-tutorial

    https://dev.gmarket.com/33

    https://www.youtube.com/watch?v=zMAX7g6rO_Y&ab_channel=우아한테크

    '🌱 spring' 카테고리의 다른 글

    Transactional Outbox Pattern  (0) 2024.04.23
    @TransactionalEventListener 적용해보기 😎  (0) 2024.03.17
    🐱 Tomcat  (0) 2023.03.12
    ThreadLocal  (0) 2023.01.18
    🌊 Connection Pool  (0) 2023.01.13

    댓글

Designed by Tistory.