동적 검색 구현 - QueryDSL 사용

이다혜·2023년 12월 18일

실습 코드 https://github.com/leedahye426/springboot-jpa

1. 검색 조건을 리스트에 담기

List<BooleanExpression> conditions = new ArrayList<>();
  • BooleanExpression
    : QueryDSL에서 사용되는 논리적인 조건을 표현하기 위한 인터페이스

2. 검색 조건 추가

각 검색 조건에 해당하는 부분을 리스트에 추가한다.

		if (kwTypes.contains("authorUsername")) {
            conditions.add(article.author.username.containsIgnoreCase(kw));
        }

        if (kwTypes.contains("title")) {
            conditions.add(article.title.containsIgnoreCase(kw));
        }

        if (kwTypes.contains("body")) {
            conditions.add(article.body.containsIgnoreCase(kw));
        }

        if (kwTypes.contains("tagContent")) {
            conditions.add(article.tags.any().content.eq(kw));
        }

        if (kwTypes.contains("commentAuthorUsername")) {
            conditions.add(article.comments.any().author.username.containsIgnoreCase(kw));
        }

        if (kwTypes.contains("commentBody")) {
            conditions.add(article.comments.any().body.containsIgnoreCase(kw));
        }
  • containsIgnoreCase()
    : QueryDSL에서 제공하는 메서드로, 문자열을 대소문자를 무시하고 특정 문자열이 포함되어 있는지 검사한다.
        

3. 조건 리스트를 OR 조건으로 결합

BooleanExpression combinedCondition = conditions.stream()
        .reduce(BooleanExpression::or)
        .orElse(null);

4. 최종 조건 적용

결합된 조건을 쿼리에 적용

if (combinedCondition != null) {
	builder.and(combinedCondition);
}

+ 페이징 처리

		// 정렬 조건 적용
        for (Sort.Order o : pageable.getSort()) {
            PathBuilder pathBuilder = new PathBuilder(article.getType(), article.getMetadata());
            articlesQuery.orderBy(new OrderSpecifier(o.isAscending() ? Order.ASC : Order.DESC, pathBuilder.get(o.getProperty())));
        }

        // 페이징 조건 적용
        articlesQuery.offset(pageable.getOffset()).limit(pageable.getPageSize());

        // 총 결과 수를 가져오기 위한 쿼리 작성
        JPAQuery<Long> totalQuery = jpaQueryFactory
                .select(article.count())
                .from(article)
                .where(builder);

        // 페이징된 결과와 총 결과 수를 가져와서 Page 객체로 변환
        return PageableExecutionUtils.getPage(articlesQuery.fetch(), pageable, totalQuery::fetchOne);
   

0개의 댓글