Study/Java Spring Boot

QueryDSL기능 사용방법 및 설정 (검색기능) 기본

kahaha 2023. 3. 10. 00:46

rest api요청을 보낼때 해당 엔티티에 대한 검색기능을 사용할 수 있는 기술이다.

 

- 먼저 build.gradle 추가

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    runtimeOnly 'com.mysql:mysql-connector-j'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-data-rest' // data rest기능 / api빠르게만들수있음
    implementation 'org.springframework.data:spring-data-rest-hal-explorer' // 해당내용을 시각적으로 보는것
    runtimeOnly 'com.h2database:h2'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    // queryDSL 설정
    // 엔티티 검색기능 사용 가능
    implementation "com.querydsl:querydsl-jpa"
    implementation "com.querydsl:querydsl-core"
    implementation "com.querydsl:querydsl-collections"
    annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jpa" // querydsl JPAAnnotationProcessor 사용 지정
    annotationProcessor "jakarta.annotation:jakarta.annotation-api" // java.lang.NoClassDefFoundError (javax.annotation.Generated) 대응 코드
    annotationProcessor "jakarta.persistence:jakarta.persistence-api" // java.lang.NoClassDefFoundError (javax.annotation.Entity) 대응 코드
}

tasks.named('test') {
    useJUnitPlatform()
}

// Querydsl 설정부
def generated = 'src/main/generated'  //파일경로  
// build디렉터리 안에 있는걸 눈에 보이게 꺼내옴
// ide같은 툴을 사용해서 발생할 수 있는 잠재적 문제를 해결하기위함

// querydsl QClass 파일 생성 위치를 지정
tasks.withType(JavaCompile) {
    options.getGeneratedSourceOutputDirectory().set(file(generated))
}

// java source set 에 querydsl QClass 위치 추가
sourceSets {
    main.java.srcDirs += [ generated ]
}

// gradle clean 시에 QClass 디렉토리 삭제
clean {
    delete file(generated)  //build clean할때 해당 파일도 같이 삭제

- Article 엔티티에 대한 레파지토리

package main22.community.repository;

import com.querydsl.core.types.dsl.DateTimeExpression;
import com.querydsl.core.types.dsl.StringExpression;
import main22.community.domain.entity.Article;
import main22.community.domain.entity.QArticle;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer;
import org.springframework.data.querydsl.binding.QuerydslBindings;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
//@Repository안붙여도 정상동작함 상속하는 클래스에 이미 붙어있음
@RepositoryRestResource // spring data rest 사용하기 위함
public interface ArticleRepository extends
        JpaRepository<Article, Long>,
        QuerydslPredicateExecutor<Article>, //해당 엔티티 안에있는 모든 검색기능을 추가해줌 // 완전 동일해야만 동작
        QuerydslBinderCustomizer<QArticle> // 부분검색, 대소문자 구분 등을 위함
{
    @Override
    default void customize(QuerydslBindings bindings, QArticle root){
        //Article에 대해 선택적인 필드에 대한 검색
        bindings.excludeUnlistedProperties(true); //리스팅 하지 않은 프로퍼티 검색 제외
        bindings.including(root.title, root.content, root.hashtag, root.createdAt, root.createdBy); //검색 컬럼
        bindings.bind(root.title).first(StringExpression::containsIgnoreCase); // like '%${v}%'/ 부분검색
        bindings.bind(root.content).first(StringExpression::containsIgnoreCase);
        bindings.bind(root.hashtag).first(StringExpression::containsIgnoreCase);
        bindings.bind(root.createdAt).first(DateTimeExpression::eq);//원하는 날짜검색 /시분초 동일하게 넣어야함
        bindings.bind(root.createdBy).first(StringExpression::containsIgnoreCase);
    }
}

- application.yml 설정부

spring:
  data: # spring data rest - 관련 설정
    rest:
      base-path: /api  #endpoint start path
      detection-strategy: annotated

 

article엔티티의 title 테이블 검색방법 ex) http://localhost:8080/api/articles?title="(부분)검색" 으로 사용하면 된다