我正在使用 hql 来处理一个复杂的过滤器项目 API,并且在 FilterProjectByLocationRequestDto 中有一个“类型”参数,具有以下逻辑:
我知道 hql 有这些语法
但我只是想出了如下的检查空逻辑,不知道如何将它与 type =1, 2 时的 case 逻辑结合起来。请帮我解决这个逻辑!!!。这是对象:
项目存储库
package com.levitate.projectbe.dao.project;
import com.levitate.projectbe.dto.filter.FilterProjectByLocationRequestDto;
import com.levitate.projectbe.entity.project.Project;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.QueryHint;
import java.util.List;
import java.util.Optional;
@Transactional(rollbackFor = Throwable.class)
public interface ProjectRepository extends JpaRepository<Project, Integer>, JpaSpecificationExecutor<Project> {
@Query(value = "SELECT p from Project p " +
"LEFT JOIN FETCH p.categoryBlocksList cb " +
"LEFT JOIN FETCH cb.blocks bl " +
"LEFT JOIN FETCH p.location l " +
"LEFT JOIN FETCH bl.planList pl " +
"LEFT JOIN FETCH pl.segmentList sl " +
"LEFT JOIN FETCH sl.floorSegmentList fl " +
"LEFT JOIN FETCH sl.segmentLayoutList sll " +
"LEFT JOIN FETCH sll.layout layout " +
"LEFT JOIN FETCH p.essentials e " +
"LEFT JOIN FETCH p.tags t " +
"LEFT JOIN FETCH p.facilities f " +
"WHERE l.id = :#{#filterProjectByLocationRequestDto.locationId} " +
"AND fl.status = :#{#filterProjectByLocationRequestDto.availableStatus} " +
"AND fl.price <= :#{#filterProjectByLocationRequestDto.totalBudgetDto.max} AND fl.price >= :#{#filterProjectByLocationRequestDto.totalBudgetDto.min} " +
"AND sl.viewStar = :#{#filterProjectByLocationRequestDto.viewRating} " +
"AND layout.bedroom = :#{#filterProjectByLocationRequestDto.numberOfBed} " +
// the logic I'm having trouble
// the countQuery don't have this condition yet
"AND (:#{#filterProjectByLocationRequestDto.getType()} is null or e.id = :#{#filterProjectByLocationRequestDto.getType()}) " +
"AND (:#{#filterProjectByLocationRequestDto.getEssentialsList()} is null or e.id in :#{#filterProjectByLocationRequestDto.getEssentialsList()}) " +
"AND (:#{#filterProjectByLocationRequestDto.getTagsList()} is null or t.id in :#{#filterProjectByLocationRequestDto.getTagsList()}) " +
"AND (:#{#filterProjectByLocationRequestDto.getFacilitysList()} is null or f.id in :#{#filterProjectByLocationRequestDto.getFacilitysList()}) ",
countQuery = "SELECT distinct count(p) from Project p " +
"LEFT JOIN p.categoryBlocksList cb " +
"LEFT JOIN cb.blocks bl " +
"LEFT JOIN p.location l " +
"LEFT JOIN bl.planList pl " +
"LEFT JOIN pl.segmentList sl " +
"LEFT JOIN sl.floorSegmentList fl " +
"LEFT JOIN sl.segmentLayoutList sll " +
"LEFT JOIN sll.layout layout " +
"LEFT JOIN p.essentials e " +
"LEFT JOIN p.tags t " +
"LEFT JOIN p.facilities f " +
"WHERE l.id = :#{#filterProjectByLocationRequestDto.locationId} " +
"AND fl.status = :#{#filterProjectByLocationRequestDto.availableStatus} " +
"AND fl.price <= :#{#filterProjectByLocationRequestDto.totalBudgetDto.max} AND fl.price >= :#{#filterProjectByLocationRequestDto.totalBudgetDto.min} " +
"AND sl.viewStar = :#{#filterProjectByLocationRequestDto.viewRating} " +
"AND layout.bedroom = :#{#filterProjectByLocationRequestDto.numberOfBed} " +
"AND (:#{#filterProjectByLocationRequestDto.getEssentialsList()} is null or e.id in :#{#filterProjectByLocationRequestDto.getEssentialsList()}) " +
"AND (:#{#filterProjectByLocationRequestDto.getTagsList()} is null or t.id in :#{#filterProjectByLocationRequestDto.getTagsList()}) " +
"AND (:#{#filterProjectByLocationRequestDto.getFacilitysList()} is null or f.id in :#{#filterProjectByLocationRequestDto.getFacilitysList()}) "
)
Page<Project> filterProjectByLocation(Pageable pageable, @Param("filterProjectByLocationRequestDto") FilterProjectByLocationRequestDto filterProjectByLocationRequestDto);
}
FilterProjectByLocationRequestDto
package com.levitate.projectbe.dto.filter;
import com.levitate.projectbe.dto.common.PopularFiltersDto;
import com.levitate.projectbe.dto.common.TotalBudgetDto;
import com.levitate.projectbe.enumeration.FloorSegmentStatus;
import com.levitate.projectbe.enumeration.SpecialType;
import com.levitate.projectbe.util.ApiUtil;
import lombok.*;
import java.util.List;
import java.util.Map;
@Getter
@Setter
@Builder
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class FilterProjectByLocationRequestDto {
private final FloorSegmentStatus availableStatus = FloorSegmentStatus.AVAILABLE;
Integer locationId;
String totalBudget;
TotalBudgetDto totalBudgetDto;
String popularFilters;
List<PopularFiltersDto> popularFiltersList;
Integer viewRating;
Integer numberOfBed;
Integer type;
Map<SpecialType, List<Integer>> sepratePopularFilterList;
List<Integer> tagsList;
List<Integer> essentialsList;
List<Integer> facilitysList;
public static void sepratePopularFilter(List<PopularFiltersDto> popularFiltersList, FilterProjectByLocationRequestDto dto) {
dto.setSepratePopularFilterList(ApiUtil.getVariableSeparator(popularFiltersList));
if (dto.getSepratePopularFilterList() != null) {
dto.setTagsList(dto.getSepratePopularFilterList().get(SpecialType.TAGS) != null ? dto.getSepratePopularFilterList().get(SpecialType.TAGS) : null);
dto.setEssentialsList(dto.getSepratePopularFilterList().get(SpecialType.ESSENTIAL) != null ? dto.getSepratePopularFilterList().get(SpecialType.ESSENTIAL) : null);
dto.setFacilitysList(dto.getSepratePopularFilterList().get(SpecialType.FACILITY) != null ? dto.getSepratePopularFilterList().get(SpecialType.FACILITY) : null);
}
}
}