기본 검색기능은 위 클래스를 상속(extends
)받음으로써 구현할 수 있다.
public interface ArticleRepository extends
JpaRepository<Article, Long>,
QuerydslPredicateExecutor<Article>{}
이런 식으로 뒤에 엔티티를 적어주는데, 이 엔티티 안에 있는 모든 필드에 대한 기본 검색기능을 추가해준다.
이 때 기본 검색기능은 대소문자를 구분하지 않고, 전체 입력값 검색을 의미한다.
전체 입력값 검색이란, 부분검색이 되지 않음을 말한다.
HAL Explorer
를 사용해서 테스트 해보았다.
기본 검색기능에서 설정하지 못한 세부 기능을 설정할 수 있다.
마찬가지로 QuerydslBinderCustomizer
를 상속받는다.
public interface ArticleRepository extends
JpaRepository<Article, Long>,
QuerydslPredicateExecutor<Article>,
QuerydslBinderCustomizer<QArticle> {}
자바는 원래 단일상속만 가능하지만, 인터페이스에서는 다중상속이 가능하다.
그리고 인터페이스 안에서 QuerydslBinderCustomizer
의 customize
메소드를 override
함으로써 검색에 대한 세부 기능을 재정의 할 수 있다.
원래는 인터페이스 파일이라 이 안에서 원래 구현을 넣을 수 없지만, Java8
부터 가능해졌다.
@Override
default void customize(QuerydslBindings bindings, QArticle root){
bindings.excludeUnlistedProperties(true);
bindings.including(root.title, root.content, root.hashtag, root.createdAt, root.createdBy);
bindings.bind(root.title).first(StringExpression::containsIgnoreCase);
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);
}
bindings.excludeUnlistedProperties(true);
현재 QuerydslPredicateExecutor
(기본검색기능)에 의해서 엔티티에 있는 모든 필드에 대한 검색이 되고 있다. 우리가 원하는 필드만 설정하기 위해서 사용한다.
true
로 하면 list하지 않은 프로퍼티는 검색에서 제외한다. (기본값은 false
)
bindings.including(root.title, root.content, root.hashtag, root.createdAt, root.createdBy);
검색을 원하는 필드를 추가한다.
bindings.bind(root.title).first(StringExpression::likeIgnoreCase); // like ''
bindings.bind(root.title).first(StringExpression::containsIgnoreCase); // like '%%'
부분검색과 대소문자 구분을 하지 않게끔 하는 코드이다.
이 둘의 차이는 쿼리문이 다르다는 것이다.
부분검색을 하려면 검색어에 %
를 넣어주어야 하는데, likeIgnoreCase
를 사용하면 이 %
를 내가 직접 넣어주어야 한다.
%
넣는 것을 수동으로 정하고 싶을 때에는 likeIgnoreCase
를 사용하고, 그렇지 않을 경우에는 containsIgnoreCase
를 사용하면 된다.
세부검색 기능 설정까지 완료하면 이렇게 일부만 입력해도 해당 입력값이 들어간 데이터를 검색할 수 있다. IgnoreCase
설정으로 인해 대소문자도 구분하지 않는다.
package com.fastcampus.projectboard.repository;
import com.fastcampus.projectboard.domain.Article;
import com.fastcampus.projectboard.domain.QArticle;
import com.querydsl.core.types.dsl.DateTimeExpression;
import com.querydsl.core.types.dsl.StringExpression;
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> {
// 검색에 대한 세부 기능 재정의
// 인터페이스 파일이라 이 안에서 원래 구현을 넣을 수 없지만, Java8부터 가능해짐
@Override
default void customize(QuerydslBindings bindings, QArticle root){
bindings.excludeUnlistedProperties(true);
// 현재 QuerydslPredicateExecutor에 의해서 엔티티에 있는 모든 필드에 대한 검색이 되고 있다. 우리가 원하는 필드만 설정하기 위해서 사용한다.
// true로 하면 list하지 않은 프로퍼티는 검색에서 제외한다. (기본값은 false)
bindings.including(root.title, root.content, root.hashtag, root.createdAt, root.createdBy); // 검색을 원하는 필드를 추가한다.
// 이 둘의 차이는 쿼리문이 다르다.
// bindings.bind(root.title).first(StringExpression::likeIgnoreCase); // like ''
bindings.bind(root.title).first(StringExpression::containsIgnoreCase); // like '%%'
// 부분검색을 하려면 검색어에 %를 넣어주어야 하는데, like를 사용하면 이 %를 내가 직접 넣어주어야 한다.
// % 넣는 것을 수동으로 정하고 싶을 때에는 like를 사용하고, 그렇지 않을 경우에는 contains를 사용하면 된다.
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);
}
}