본문 바로가기
Java/querydsl

querydsl ) String 컬럼들 동적으로 쿼리 생성

by 하이방가루 2023. 3. 19.
728x90
반응형

보통 querydsl 을 쓸 때는 Q클래스를 생성하여 컬럼명으로 체이닝을 하여 쓴다. 이렇게 하면 컬럼명을 잘못입력하면 컴파일과정에서 바로 오류가 뜨기 때문에 보통 IDE에서 빨간줄로 표시해주어서 불필요한 테스트를 줄일 수 있어서 큰 장점이 된다.

그렇다면 컬럼을 동적으로 선택하여 쿼리문을 만들려고 한다면 어떻게 해야할까?

 

예를 들어, 게시판에서 검색 영역을 제목, 내용, 태그를 동적으로 선택하여 특정 단어를 검색하는 기능을 만들려고 할 경우. 경우의 수는 컬럼 1개인 경우 3가지, 컬럼 2개인 경우 3가지, 컬럼 3개인 경우 1가지로 총 7가지 경우의 수가 생기고 이를 분기처리한다면 코드의 가독성을 떨어질 것이다.

 

그래서 프론트에서 검색 영역을 배열로 보내주고 배열에서 각 검색영역에서 특정 단어를 포함하는지 검색하는 빌더를 or로 묶어버리게 좋겠다는 생각을 하게 되었고, PathBuilder에 대해서 알게 되어 이를 이용하여 기능을 만들기로 하였다.

출처 : https://www.baeldung.com/rest-api-search-language-spring-data-querydsl

 

Request json

{
    "searchable[]" : List<String>,
    "keyword" : String
}

위와 같이 프론트에서 json 요청을 보내면 Controller Layer에서 Service Layer로 변수를 전달하여

// Service
public Iterable<User> searchContainKeywordInColumns(List<String> columns, String keyword) {
	
    QBbs bbs = QBbs.bbs; // rename
    PathBuilder<Bbs> bbsEntityPath = new PathBuilder<>(Bbs.class, bbs.getMetaData());	// Bbs : JPA엔티티(모델)
    BooleanBuilder builder = new BooleanBuilder();
    
    for (String column : columns) {
    	
        builder.or(bbsEntityPath.getString(column) // data type이 String인 column선택
        			.contains(keyword));
    }
    
    return queryFactory.selectFrom(bbs)
    	    .where(builder)
            .fetch();
}

위와 같이 builder를 생성하여 repository에서 원하는 데이터를 불러올 수 있다.

출처에서는 테이블 명을 문자열로 하드코드하여 넣어주었지만 Q클래스를 이용한다면 이런 하드코드를 없앨 수 있다.

 

출처에 가면 기능을 좀 더 유연하게 만드는 법과 테스트 코드를 볼 수 있어서 출처에 가서 자세히 살펴보기를 권한다.

 

출처 : https://www.baeldung.com/rest-api-search-language-spring-data-querydsl

728x90
반응형

댓글