본문 바로가기
Spring/JPA

querydsl 다중 조건 검색 만들기

by YoonJong 2023. 2. 5.
728x90

https://josteady.tistory.com/848

이전에 학습하려고 간단히 예제를 만들어보고, 개인프로젝트에 적용해보려고 합니다.

전 포스팅에서는 0원 이상 0원 이하의 조건으로 검색했으나, 이번에는 카테고리를 추가해보려고 합니다.

 

querydsl 를 위한 customRepository는 이전에 만들었으니 바로 코드를 확인해보겠습니다.

public class GoodsRepositoryImpl implements GoodsRepositoryCustom {

    private final JPAQueryFactory queryFactory;
    private final CategoryRepository categoryRepository;

    public GoodsRepositoryImpl(EntityManager em, CategoryRepository categoryRepository) {
        this.queryFactory = new JPAQueryFactory(em);
        this.categoryRepository = categoryRepository;
    }

    @Override
    public Page<GoodsResponse> searchBetweenPrice(GoodsSearchCondition condition, Pageable pageable) {

        List<GoodsResponse> content = queryFactory
                .select(new QGoodsResponse(goods))
                .from(goods)
                .innerJoin(goods.category, category1)
                .where(
                        betweenPrice(condition.getPriceMin(), condition.getPriceMax()),
                        categoryEq(condition))
                .orderBy(goods.price.desc())
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();

        int total = content.size();
        return new PageImpl<>(content, pageable, total);

    }

    private BooleanExpression categoryEq(GoodsSearchCondition condition) {
        Category findCategory = categoryRepository.findByCategory(condition.getCategory()).get();

        // 화면에서 카테고리 목록을 선택할 수 있다 -> null 경우 없음
        return goods.category.eq(findCategory);
    }

    private BooleanExpression betweenPrice(Integer priceMin, Integer priceMax) {
        // 상품의 최댓값
        int maxPrice = 999999999;

        // null 원 이상 000원 이하
        if (priceMin == null && priceMax != null) {
            return priceLoe(priceMax).and(priceGoe(0));
            // 000원 이상 null 원 이하
        } else if (priceMin != null && priceMax == null) {
            return priceLoe(maxPrice).and(priceGoe(priceMin));
            // null 원 이상 null 원 이하
        } else if (priceMin == null && priceMax == null) {
            return priceLoe(maxPrice).and(priceGoe(0));
        } else {
            // 000원 이상 000원 이하
            return priceLoe(priceMax).and(priceGoe(priceMin));
        }
    }

    private BooleanExpression priceLoe(Integer priceMin) {
        return priceMin != null ? goods.price.loe(priceMin) : null;
    }

    private BooleanExpression priceGoe(Integer priceMax) {
        return priceMax != null ? goods.price.goe(priceMax) : null;
    }
}

 

조금 더 집중적으로 봐야할 부분은 queryFactory 의 where 절입니다.

조건이 총 2개 들어갔으며, categoryEq() 메서드를 따로 생성해주었습니다.

private BooleanExpression categoryEq(GoodsSearchCondition condition) {
    Category findCategory = categoryRepository.findByCategory(condition.getCategory()).get();

    // 화면에서 카테고리 목록을 선택할 수 있다 -> null 경우 없음
    return goods.category.eq(findCategory);
}

해당 부분을 구현했습니다.

참고로, GoodsSearchCondition 에서 상품의 최소값, 최대값, 카테고리 이름 필드를 가지고 있습니다.

categoryRepository 에서 파라미터로 받은 값으로 카테고리를 찾은 후, goods.category.eq 를 이용해서 상품을 찾을 수 있습니다.

 

 

테스트는 테스트로직을 몇시간동안 여러가지 방법으로 짜보았는데 계속된 실패(ㅠㅠ)로 배포되어있는 SWAGGER 문서와 POSTMAN으로 테스트해보았습니다.

검색해볼 조건은 아래와 같습니다.

1. 카테고리명 : 하의

2. 최소금액 : 0원

3. 최대금액 : 40000원

4. 정렬순서 : price 내림차순 ( queryFactory에서 설정해주었습니다. )

 

테스트 결과 조건과 같이 출력되는 것을 볼 수 있습니다. ( 데이터가 길어 줄였습니다. )

728x90

댓글