public class AirSpecification {
public static Specification<Air> filterBy(
List<String> airlines, List<String> departs, List<String> arrives, String departTimeStart, String departTimeEnd, Integer minPrice, Integer maxPrice
) {
return (root, query, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
// 항공사 필터 (체크박스 선택)
if (airlines != null && !airlines.isEmpty()) {
predicates.add(root.get("airline").in(airlines));
}
// 출발지 필터 (체크박스 선택)
if (departs != null && !departs.isEmpty()) {
predicates.add(root.get("depart").in(departs));
}
// 도착지 필터 (체크박스 선택)
if (arrives != null && !arrives.isEmpty()) {
predicates.add(root.get("arrive").in(arrives));
}
// 출발 시간 필터
if (departTimeStart != null && departTimeEnd != null) {
predicates.add(criteriaBuilder.between(root.get("depart_time"), departTimeStart, departTimeEnd));
}
// 가격 범위 필터
if (minPrice != null && maxPrice != null) {
predicates.add(criteriaBuilder.between(root.get("price"), minPrice, maxPrice));
}
return predicates.isEmpty() ? criteriaBuilder.conjunction() : criteriaBuilder.and(predicates.toArray(new Predicate[0]));
};
}
}
처음 필터 적용 방법 Specification 적용
복잡한 쿼리를 처리하기 위함
사용하기 위해 하단 레포지토리에 추가해줘야함
public interface AirRepository extends JpaRepository<Air, Long>, JpaSpecificationExecutor<Air> {
// 페이징과 정렬을 지원하는 Specification 기반 쿼리
Page<Air> findAll(Specification<Air> spec, Pageable pageable);
}
만든 쿼리 사용방법
@RestController
@RequiredArgsConstructor
@RequestMapping("/air")
public class AirController {
private final AirService airService;
// 전체 항공 상품 (페이징)
@GetMapping
public Page<Air> getAllAir(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "price,asc") String sortBy
) {
Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Order.by(sortBy.split(",")[0]).with(Sort.Direction.fromString(sortBy.split(",")[1]))));
return airService.getAllAirList(pageable);
}
// 필터링된 항공 상품 (페이징)
@GetMapping("/search")
public Page<Air> searchAir(
@RequestParam(required = false) List<String> airlines,
@RequestParam(required = false) List<String> departs,
@RequestParam(required = false) List<String> arrives,
@RequestParam(required = false) String departTimeStart,
@RequestParam(required = false) String departTimeEnd,
@RequestParam(required = false) Integer minPrice,
@RequestParam(required = false) Integer maxPrice,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "price,asc") String sortBy
) {
Specification<Air> spec = AirSpecification.filterBy(airlines, departs, arrives, departTimeStart, departTimeEnd, minPrice, maxPrice);
Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Order.by(sortBy.split(",")[0]).with(Sort.Direction.fromString(sortBy.split(",")[1]))));
return airService.getFilteredAirList(spec, pageable);
}
}
@Service
@RequiredArgsConstructor
public class AirService {
private final AirRepository airRepository;
// 필터 적용 + 페이징 처리된 항공 상품 조회
public Page<Air> getFilteredAirList(Specification<Air> spec, Pageable pageable) {
return airRepository.findAll(spec, pageable);
}
// 필터 없이 전체 항공 상품 조회 (처음 페이지 진입 시)
public Page<Air> getAllAirList(Pageable pageable) {
return airRepository.findAll(pageable);
}
}
다음에 querydsl로 조건을 더 걸어서 변경작업중
'Project > Team Project(딱좋은여행)' 카테고리의 다른 글
| 서버 db에 값 미리 넣는 방법 (0) | 2025.04.29 |
|---|---|
| 트러블슈팅 - admin 빌드 오류 (0) | 2025.04.07 |
| 트러블슈팅 - queryDsl 오류 해결방법 (0) | 2025.04.04 |
| 공공데이터 포털 인코딩 오류 트러블 (0) | 2025.03.06 |
| 딱좋은 여행 코드 정리 (엔티티 연관관계 매핑) (1) | 2025.02.27 |