🌱 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://www.youtube.com/watch?v=zMAX7g6rO_Y&ab_channel=우아한테크