티스토리 뷰

안녕하세요 강정호 입니다.

 

오늘은 Querydsl 의존성 추가와 api 검색옵션을 추가하는 개발을 하였습니다.

Querydsl이 무엇이고 검색기능 구현을 위해서 어떻게 사용하는지 알아보겠습니다.

 

Querydsl이란 무엇인가?

Querydsl은 자바언어를 사용하여 타입세이프한 쿼리를 작성하는데에 도움을 주는 오픈소스 프레임워크이다.

 

기존에는 Mybatis를 이용해서 직접 SQL문을 작성하거나, JPQL을 사용하여 쿼리문을 만들었다.

하지만 이런 경우 쿼리문 상에 오타가 있을 수 있기 때문에 관리가 어려웠다. 그리고 DB의 종류(오라클, Mysql, MongoDB 등)에 따라서 쿼리문을 다르게 작성해주어야 했다. 하지만 이를 보완하는 것이 Querydsl이다.

Querydsl은 데이터베이스에 상관없이 일관성 있게 객체로 쿼리를 작성할 수 있도록 도와줍니다.

Querydsl은 ORM인 JPA와 함께 사용하여 타입 세이프한 쿼리 작성에 도움을 줍니다.

 

Querydsl의 장점

1. 쿼리의 가독성이 좋다 : 자바코드, 객체를 사용해서 쿼리를 작성하기 때문에 가독성이 좋다

2. 쿼리에 일관성이 있다 : DB 종류에 상관없이 쿼리를 일관적으로 작성 가능

3. 오류를 미리 발견 : 컴파일 시점에 오류를 잡아낼 수 있으므로 런타임 오류 발생을 감소시킬 수 있다.

 

Spring Data JPA와 Querydsl을 주로 같이 사용한다.

 

 

Querydsl 의존성 추가

// queryDSL 설정
// 해결 블로그 : https://l4279625.tistory.com/146
implementation "com.querydsl:querydsl-jpa:5.0.0:jakarta"
implementation "com.querydsl:querydsl-core"
implementation "com.querydsl:querydsl-collections"
annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" // 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) 대응 코드

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

/** Q클래스는 보통 빌드 폴더에 생성된다. 근데 왜 generated 폴더에 가져오나? 어떤 IDE를 사용해서 빌드할 때 발생하는 에러를 방지하기 위해서.
 Gradle 빌드 도구가 스캔하는 영역과 IDE가 스캔하는 영역에 차이가 있다. 스캔을 두 곳에서 하다보니까 중복 생성되어 충돌.
 그래서 강제로 generated 폴더로 강제로 설정.
 */
// Querydsl 설정부
def generated = 'src/main/generated'

// 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)
}

Querydsl은 @Entity 어노테이션을 선언한 클래스를 탐색하고, JPAannotationProcessor을 이용해서 Q 클래스를 생성합니다.

Q 클래스란?

Querydsl을 사용할 때, Q클래스를 사용하므로서 타입 safe한 쿼리를 생성할 수 있도록 도와주는 클래스.

 

implementation에는 querydsl 의존성을 추가해준다. annotationProcessor을 추가해주는 이유는 javax -> jakarta로 변경되었기 때문에 변경해준다. 

 

그리고 위와 같이 Querydsl의 Q클래스 생성에 대한 설정을 같이 해줘야 한다.

 

Querydsl의 활용방법

 

Article 엔티티에 대해서 title, content, hashtag, createdAt, createdBy 조건으로 검색할 수 있는 기능을 추가한다.

package com.marathon.board.repository;

import com.marathon.board.domain.Article;
import com.marathon.board.domain.QArticle;
import com.querydsl.core.types.dsl.DateTimeExpression;
import com.querydsl.core.types.dsl.SimpleExpression;
import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.core.types.dsl.StringExpressions;
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;

@RepositoryRestResource
public interface ArticleRepository extends
    JpaRepository<Article, Long> ,
    QuerydslPredicateExecutor<Article>,
    QuerydslBinderCustomizer<QArticle>
{
    @Override
    default void customize(QuerydslBindings bindings, QArticle root) {
        // 선택적으로 특정 필드에 대해서 검색 가능하게 하기 위한 장치
        // 인터페이스인데 인터페이스 내부에 메서드를 구현할 수 있다. => java8부터 가능
        bindings.excludeUnlistedProperties(true); //일단 검색에서 제외하도록 하고
        bindings.including(root.title, root.content, root.hashTag, root.createdAt, root.modifiedAt); //이 필드들만 검색 대상
        bindings.bind(root.title).first((StringExpression::containsIgnoreCase)); // like '%value%' 쿼리를 생성한다
        bindings.bind(root.content).first((StringExpression::containsIgnoreCase)); // like '%value%' 쿼리를 생성한다
        bindings.bind(root.hashTag).first((StringExpression::containsIgnoreCase)); // like '%value%' 쿼리를 생성한다
        bindings.bind(root.createdAt).first((DateTimeExpression::eq)); // like '%value%' 쿼리를 생성한다
        bindings.bind(root.createdBy).first((StringExpression::containsIgnoreCase)); // like '%value%' 쿼리를 생성한다

    }

}

QuerydslPredicateExecutor : 

 

 

 

 

 

 

 

 

Querydsl 이란?

 

QuerydslPredicateExecutor
QuerydslBinderCustomizer

Querydsl에서 검색 기능 개발을 위한 기술 공부

 

 

인터페이스에서 메서드를 구현할 수 있는 기술

 

 

'Back-end > Spring Boot' 카테고리의 다른 글

[게시판 만들기] rebase merge  (0) 2023.05.07
09. 게시글 페이지 만들기  (0) 2023.04.05
Spring Data REST 테스트  (0) 2023.03.30
[JPA] @MappedSuperclass, @EntityListners  (0) 2023.03.25
[패스트캠퍼스 6번쨰 수업]  (0) 2018.11.10
댓글