서버

SpringBoot에 QueryDSL 적용하기(Maven)

고태광이 2019. 7. 14. 15:09

오늘은 SpringBoot 에 Mongo Query 적용하는 법을 알아보려 합니다.

 

우선 QueryDSL이란 무엇일까요?

Type-Safe 한 쿼리를 위한 스프링에서 제공하는 Domain Specific Language 입니다. 

쿼리를 자바로 Type-Safe하게 개발 할 수 있게 제공한 프레임워크입니다. 

Repository 인터페이스에서 메소드명으로 쿼리문을 만들기 까다로울 때 유용하게 만들 수 있습니다.

 

queryDSL 을 사용하기위해 의존성 추가해야하는데요

<dependency>
      <groupId>com.querydsl</groupId>
      <artifactId>querydsl-mongodb</artifactId>
</dependency>

<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>
                    <id>jpa-processor</id>
                    <goals>
                         <goal>process</goal>
                     </goals>
                     <configuration>
                          <outputDirectory>target/generated-sources/java</outputDirectory>
                          <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                      </configuration>
                </execution>
                <execution>
                     <id>mongodb-processor</id>
                     <goals>
                          <goal>process</goal>
                      </goals>
                      <configuration>
                           <outputDirectory>target/generated-sources/java</outputDirectory>
                           <processor>org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor</processor>
                        </configuration>
                 </execution>
         </executions>
  </plugin>

 

querydsl-apt, querydsl-jpa : QueryDsl 관련 dependency
Document class build plugin 관련 설정

 

Video Document class 추가

@Data
@Document(collection = "video")
public class Video {
    @Id
    private String id;
    private String userId;
    private String title;
    private String url;
    private String catId;
    private String thumnailUrl;
    private String regDate;
    private Integer views;
}

 

이후에 빌드를 돌리시면 QVideo class가 생성된 것을 보실 수 있습니다.

@Generated("com.querydsl.codegen.EntitySerializer")
public class QVideo extends EntityPathBase<Video> {

    private static final long serialVersionUID = -1665851156L;

    public static final QVideo video = new QVideo("video");

    public final StringPath catId = createString("catId");

    public final StringPath id = createString("id");

    public final StringPath regDate = createString("regDate");

    public final StringPath thumnailUrl = createString("thumnailUrl");

    public final StringPath title = createString("title");

    public final StringPath url = createString("url");

    public final StringPath userId = createString("userId");

    public final NumberPath<Integer> views = createNumber("views", Integer.class);

    public QVideo(String variable) {
        super(Video.class, forVariable(variable));
    }

    public QVideo(Path<? extends Video> path) {
        super(path.getType(), path.getMetadata());
    }

    public QVideo(PathMetadata metadata) {
        super(Video.class, metadata);
    }

}

내부에 가진 필드들은 실제로 Querydsl을 사용하여 쿼리를 작성할때 이용됩니다.

 

Repository를 생성해보겠습니다.

 

 

package com.kuzal.kuzalcompetition.repository;

import com.kuzal.kuzalcompetition.model.Video;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface VideoRepository extends MongoRepository<Video,String>,
        VideoCustomRepository {
}
package com.kuzal.kuzalcompetition.repository;

import com.kuzal.kuzalcompetition.model.Video;

import java.util.List;

public interface VideoCustomRepository {
    List<Video> findAll();
    Video findByTitle(String name);
}

 

package com.kuzal.kuzalcompetition.repository;

import com.kuzal.kuzalcompetition.model.Video;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.List;

import static com.kuzal.kuzalcompetition.model.QVideo.video;
import static com.kuzal.kuzalcompetition.util.MongoQueryUtil.parse;

@Slf4j
public class VideoRepositoryImpl  implements VideoCustomRepository {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public List<Video> findAll(){
        return mongoTemplate.findAll(Video.class);
    }


    // for reference
    @Override
    public Video findByTitle(String name){
        Query query = new Query();
        query.addCriteria(Criteria.where(parse(video.title)).is(name));
        return mongoTemplate.findOne(query,Video.class);
    }

}
package com.kuzal.kuzalcompetition.util;


import com.querydsl.core.types.Path;

public class MongoQueryUtil {
    public static String parse(Path path){
        String s = path.toString();
        return s.substring(s.indexOf(".")+1, s.length());
    }
}

 

위의 Query 부분을 보시면 

   query.addCriteria(Criteria.where(parse(video.title)).is(name));

이런식으로 쿼리문을 작성하시면 됩니다.