Skip to content

Latest commit

 

History

History
101 lines (83 loc) · 3.71 KB

spesification-jpa-search.md

File metadata and controls

101 lines (83 loc) · 3.71 KB
package com.alper.leasesoftprov2.leasesoft.buildings.filters;

import com.alper.leasesoftprov2.leasesoft.buildings.Building;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;

import java.util.Optional;

@Component
public class BuildingSpecification {

    public Specification<Building> filterBy(BuildingFilter filter){
        return Specification
                .where(hasBeds(filter.getBeds()))
                .and(hasBaths(filter.getBaths()))
                .and(inCity(filter.getCity()))
                .and(priceFrom(filter.getPriceFrom()))
                .and(priceTo(filter.getPriceTo()))
                .and(sizeTo(filter.getSizeTo()))
                .and(sizeFrom(filter.getSizeFrom()));
    }

    Specification<Building> hasBeds(Optional<Integer> beds){
        return (((root, query, criteriaBuilder) -> beds != null && beds.isPresent() ?
                criteriaBuilder.equal(root.get("bedrooms"),beds.get()):
                criteriaBuilder.conjunction()));
    }

    Specification<Building> hasBaths(Optional<Integer> baths){
        return (((root, query, criteriaBuilder) -> baths!=null && baths.isPresent() ?
                criteriaBuilder.equal(root.get("bathrooms"),baths.get()):
                criteriaBuilder.conjunction() ));
    }

    Specification<Building> inCity(Optional<String> city){
        return (((root, query, criteriaBuilder) ->  city!=null &&  city.isPresent() && !city.get().isEmpty() ?
                criteriaBuilder.equal(root.get("city"),city.get()):
                criteriaBuilder.conjunction()));
    }

    Specification<Building> priceFrom(Optional<Double> priceFrom){
        return (((root, query, criteriaBuilder) -> priceFrom !=null &&  priceFrom.isPresent() ?
                criteriaBuilder.greaterThanOrEqualTo(root.get("listing").get("price"),priceFrom.get()) :
                criteriaBuilder.conjunction()));
    }

    Specification<Building> priceTo(Optional<Double> priceTo){
        return (((root, query, criteriaBuilder) -> priceTo !=null  && priceTo.isPresent() ?
                criteriaBuilder.lessThanOrEqualTo(root.get("listing").get("price"),priceTo.get()) :
                criteriaBuilder.conjunction()));
    }

    Specification<Building> sizeTo(Optional<Double> sizeTo){
        return (((root, query, criteriaBuilder) -> sizeTo !=null  && sizeTo.isPresent() ?
                criteriaBuilder.lessThanOrEqualTo(root.get("size"),sizeTo.get()) :
                criteriaBuilder.conjunction()));
    }

    Specification<Building> sizeFrom(Optional<Double> sizeFrom){
        return (((root, query, criteriaBuilder) -> sizeFrom !=null  && sizeFrom.isPresent() ?
                criteriaBuilder.greaterThanOrEqualTo(root.get("size"),sizeFrom.get()) :
                criteriaBuilder.conjunction()));
    }
}
@Repository
public interface BuildingRepository  extends JpaRepository<Building,Integer> {
    List<Building> findAllByBedrooms(Integer bedrooms);
    List<Building> findAll(@Nullable Specification<Building> specification);
}
@Service
public class BuildingService {

    @Autowired
    private BuildingRepository repository;

    @Autowired
    private BuildingMapper mapper;

    @Autowired
    private BuildingSpecification buildingSpecification;

    List<BuildingDto> getBuildings(BuildingFilter filter)  {
        Specification<Building> specification = buildingSpecification.filterBy(filter);
        return repository.findAll(specification).stream().map(building -> {
            try {
                return mapper.toDTO(building);
            } catch (NotSupportedException e) {
                throw new RuntimeException(e);
            }
        }).collect(Collectors.toList());
    }
}