검색하는데 where 조건문이 계속 추가되는 문제

Terror·2024년 10월 31일

최종 프로젝트

목록 보기
12/28

Overivew

  • QueryDSL을 활용하여, 검색기능을 구현하고 테스트하던중 이상현상을 확인하고, 대처 할 수 있다

전체코드

package com.sparta.doguin.domain.outsourcing.repository;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.sparta.doguin.domain.outsourcing.entity.Outsourcing;
import com.sparta.doguin.domain.outsourcing.entity.QOutsourcing;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@Slf4j
@RequiredArgsConstructor
public class OutsourcingRepositoryQueryImpl implements OutsourcingRepositoryQuery {
    private final JPAQueryFactory q;
    private final BooleanBuilder b;

    QOutsourcing qOutsourcing = QOutsourcing.outsourcing;


    @Override
    public Page<Outsourcing> search(String title, String content, String nickname, Pageable pageable) {
        log.info("title {}", title);
        log.info("content {}", content);
        log.info("nickname {}", nickname);


        if (title != null && !title.trim().isEmpty()) {
            b.and(qOutsourcing.title.contains(title));
        }

        if (content != null && !content.trim().isEmpty()) {
            b.and(qOutsourcing.content.contains(content));
        }

        if (nickname != null && !nickname.trim().isEmpty()) {
            b.and(qOutsourcing.user.nickname.contains(nickname));
        }

        List<Outsourcing> outsourcingList = q
                .select(
                        Projections.constructor(
                                Outsourcing.class,
                                qOutsourcing.id,
                                qOutsourcing.user,
                                qOutsourcing.title,
                                qOutsourcing.content,
                                qOutsourcing.preferential,
                                qOutsourcing.work_type,
                                qOutsourcing.price,
                                qOutsourcing.recruit_start_date,
                                qOutsourcing.recruit_end_date,
                                qOutsourcing.work_start_date,
                                qOutsourcing.work_end_date,
                                qOutsourcing.area
                        )
                )
                .distinct()
                .from(qOutsourcing)
                .where(b)
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();
        return new PageImpl<>(outsourcingList, pageable, outsourcingList.size());
    }
}

무엇이 이상한가?

  • 클라이언트로부터 동일한 요청에 대해 여러번 검색 요청을 해보면 아래와같이 계속 로그에 표기된다

첫번째 검색

    from
        outsourcing o1_0 
    join
        users u1_0 
            on u1_0.id=o1_0.user_id 
    where
        o1_0.title like ? escape '!' 
    limit
        ?, ?

두번째 검색

    from
        outsourcing o1_0 
    join
        users u1_0 
            on u1_0.id=o1_0.user_id 
    where
        o1_0.title like ? escape '!' 
        and o1_0.title like ? escape '!' 
    limit
        ?, ?

세번째 검색

    from
        outsourcing o1_0 
    join
        users u1_0 
            on u1_0.id=o1_0.user_id 
    where
        o1_0.title like ? escape '!' 
        and o1_0.title like ? escape '!' 
        and o1_0.title like ? escape '!' 
    limit
        ?, ?

원인이 뭐지?

  • 난 분명 title 하나의 조건에 대해서만 검색을 하고있는데 계속 title의 검색조건이 쌓이는 모습이다
  • 저러면 저 3가지의 조건이 모두 일치하는 title에 대해서만 검색이 되기 떄문에 내가 원하는 방향이 아니다

해결방법

  • 검색기능을 구현하기위해, 동적쿼리를 해결 할 수 있는 BooleanBuilder와 같이 문제를 해결하려고 하는것은 좋았지만, 이를 Config에서 한번만 초기화 시킨 상태로 IoC에 넣으니 검색 요청을 할때마다 BooleanBuilder가 초기화되지 않아 발생되었던 문제다
  • 따라서 Config에서 Bean주입을 해주던 BooleanBuilder를 없애고 매요청마다 새로 생성하기위해 new로 만들어주었다

Config 삭제

new 생성자로 만들어주기

BooleanBuilder b = new BooleanBuilder();

문제해결 !

profile
테러대응전문가

0개의 댓글