🌱 spring

🍀 MongoDB - QueryDsl with Spring

beomsic 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=우아한테크