내배캠

최종 프로젝트 트러블슈팅(1) - pageable

muerha 2025. 1. 9. 14:50

 

 

 

상황

검색 결과를 페이징 처리하여 조회하는 기능을 구현하던 중,

 

문제

public List<ProductResDto> findAllProducts(int page, int size, String productName) {
        Pageable pageable = PageRequest.of(page, size);

        if (productName != null && !productName.isEmpty()) {
            Page<Product> productPage = productRepository.findAll(pageable);

            return productPage.stream()
                    .filter(product -> product.getName().contains(productName))  // productName을 포함하는 Product만 필터링
                    .map(product -> new ProductResDto(
                            product.getId(),
                            product.getCompany().getId(),
                            product.getName(),
                            product.getDescription(),
                            product.getPrice(),
                            product.getAddress(),
                            product.getQuantity(),
                            product.getCreatedAt(),
                            product.getUpdatedAt()
                    ))
                    .collect(Collectors.toList());
        }

        return productRepository.findAll()
                .stream()
                .map(product -> new ProductResDto(
                        product.getId(),
                        product.getCompany().getId(),
                        product.getName(),
                        product.getDescription(),
                        product.getPrice(),
                        product.getAddress(),
                        product.getQuantity(),
                        product.getCreatedAt(),
                        product.getUpdatedAt()
                ))
                .collect(Collectors.toList());
    }

 

포스트맨으로 테스트 해본 결과, 페이징 처리가 되지 않은 상태로 모든 데이터를 반환하는 것을 볼 수 있었다.

 

 

원인

findAll(pageable)을 통해 페이징 처리된 데이터를 가져왔지만 그 데이터를 메모리에서 필터링하려고 하면 필터링된 데이터에 대해서는 다시 페이징 처리가 적용되지 않기 때문이었다.

 

 

해결 

이를 해결하기 위 데이터베이스에서 필터링을 먼저 진행하는 방식으로 변경했다.

public List<ProductResDto> findAllProducts(int page, int size, String productName) {
        Pageable pageable = PageRequest.of(page, size);
        Page<Product> productPage = productRepository.findAll(pageable);

        // 상품명 검색을 통한 검색 결과 조회
        if (productName != null && !productName.isEmpty()) {
            productPage = productRepository.findByNameContaining(productName, pageable);
        }

        return productPage.getContent().stream()
                .map(product -> new ProductResDto(
                        product.getId(),
                        product.getCompany().getId(),
                        product.getName(),
                        product.getDescription(),
                        product.getPrice(),
                        product.getAddress(),
                        product.getQuantity(),
                        product.getCreatedAt(),
                        product.getUpdatedAt()
                ))
                .collect(Collectors.toList());

    }

 

findByNameContaining(productName, pageable)을 사용하여 상품명을 기준으로 DB에서 필터링을 진행하고, 그 결과에 대해 페이징 처리를 적용하도록 수정하였다.

 

 

 

결과 

변경 결과, productName이 주어지면 해당 이름을 포함하는 상품들만 필터링하고, 페이징 처리된 상태로 결과가 반환되는 것을 확인했다.

이를 통해 불필요한 데이터를 메모리에 올리지 않게 되어 데이터가 효율적으로 처리되는 결과를 얻을 수 있었다.

 

+

이후 리팩토링 과정에서 QueryDSL을 사용해 복잡한 검색 조건을 보다 효율적으로 처리할 수 있도록 해주었다.