如何结合 hql 检查为 null + hql if else 条件

时间:2021-05-06 10:17:56

标签: java spring-boot hibernate jpa hql

我正在使用 hql 来处理一个复杂的过滤器项目 API,并且在 FilterProjectByLocationRequestDto 中有一个“类型”参数,具有以下逻辑:

  • 如果参数“type”为空,则查找所有项目
  • 如果参数“type”为 1,则查找所有 type = 1 的项目
  • 如果参数 "type" 为 2,则查找 type = 2 的所有项目

我知道 hql 有这些语法

  • isNull 语法:(param2 IS NULL OR col2 = param2)
  • case 语法:case ... when ... then ... else ... end

但我只是想出了如下的检查空逻辑,不知道如何将它与 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);
        }
    }
}

0 个答案:

没有答案