Spring Boot:Query方法中的可选参数查询

时间:2018-10-11 06:06:18

标签: java hibernate spring-boot jpql

我是Spring引导和休眠的新手。在这里,我尝试运行基于搜索的可选参数查询,可以在其中按名称,国家/地区等进行搜索。如果我将此字段保留为空,则查询应全部列出。但是问题是我的方法返回所有数据而忽略了我的搜索参数。我的模型课看起来像

@Entity(name="MLFM_ORDER_OWNER")
public class ModelOrderOwner {

    @Id @GenericGenerator(name = "custom_sequence", strategy = 
            "com.biziitech.mlfm.IdGenerator")
    @GeneratedValue(generator = "custom_sequence")
    @Column(name="ORDER_OWNER_ID")
    private Long orderOwnerId;

    @Column(name="OWNER_NAME")
    private String ownerName;

    @OneToOne
    @JoinColumn(name="BUSINESS_TYPE_ID")
    private ModelBusinessType businessTypeId;

    @Column(name="SHORT_CODE")
    private String shortCode;


    @ManyToOne
    @JoinColumn(name="OWNER_COUNTRY")
    private ModelCountry ownerCountry;
// getter setter..

我的存储库界面看起来像

public interface OrderOwnerRepository extends 

    JpaRepository<ModelOrderOwner,Long>{
        @Query("select a from MLFM_ORDER_OWNER a where a.businessTypeId.typeId=coalsec(:typeId,a.businessTypeId.typeId) and a.ownerCountry.countryId=coalsec(:countryId,a.ownerCountry.countryId) and a.ownerName LIKE %:name and a.shortCode LIKE %:code")
        public List <ModelOrderOwner> findOwnerDetails(@Param("typeId")Long typeId,@Param("countryId")Long countryId,@Param("name")String name,@Param("code")String code);

    }

这是我在控制器中的方法

@RequestMapping(path="/owners/search")
     public String getAllOwner(Model model,@RequestParam("owner_name") String name,@RequestParam("shortCode") String code,

                            @RequestParam("phoneNumber") String phoneNumber,@RequestParam("countryName") Long countryId,
                            @RequestParam("businessType") Long typeId
             ) {
 model.addAttribute("ownerList",ownerRepository.findOwnerDetails(typeId, countryId, name, code));

            return "data_list";
    }

在这方面有人可以帮助我吗?好吗?

3 个答案:

答案 0 :(得分:2)

不知道如何,但是下面的代码对我有用

@Query("select a from MLFM_ORDER_OWNER a  where a.businessTypeId.typeId=COALESCE(:typeId,a.businessTypeId.typeId) and a.ownerCountry.countryId=COALESCE(:countryId,a.ownerCountry.countryId) and a.ownerName LIKE %:name and a.shortCode LIKE %:code")
    public List <ModelOrderOwner> findOwnerDetails(@Param("typeId")Long typeId,@Param("countryId")Long countryId,@Param("name")String name,@Param("code")String code); 

并在控制器中

@RequestMapping(path="/owners/search")
     public String getAllOwner(Model model,@RequestParam("owner_name") String name,@RequestParam("shortCode") String code,

                            @RequestParam("phoneNumber") String phoneNumber,@RequestParam("countryName") Long countryId,
                            @RequestParam(value = "active", required = false) String active, @RequestParam("businessType") Long typeId
             ) {




        if(typeId==0)
            typeId=null;
        if(countryId==0)
            countryId=null;

         model.addAttribute("ownerList",ownerRepository.findOwnerDetails(typeId, countryId, name, code, status));

            return "data_list";
    }

答案 1 :(得分:1)

JPQL不支持可选参数。 在JPQL中没有简单的方法可以做到这一点。您将必须使用 OR 运算符编写多个 WHERE 子句。

请参考以下答案以回答类似的问题:Answer 1Answer 2

PS:您可能希望针对您的用例来研究Query by Example。它支持处理空参数。

答案 2 :(得分:0)

使用 JpaSpecificationExecutor //import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

第 1 步:在您的 JPA 存储库中实现 JpaSpecificationExecutor

例如:

public interface TicketRepo extends JpaRepository<Ticket, Long>, JpaSpecificationExecutor<Ticket> {

第 2 步现在要根据可选参数获取票证,您可以使用 CriteriaBuilder 构建规范查询

例如:

public Specification<Ticket> getTicketQuery(Integer domainId, Calendar startDate, Calendar endDate, Integer gameId, Integer drawId) {
    return (root, query, criteriaBuilder) -> {
        List<Predicate> predicates = new ArrayList<>();

        predicates.add(criteriaBuilder.equal(root.get("domainId"), domainId));
        predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createdAt"), startDate));
        predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("createdAt"), endDate));

        if (gameId != null) {
            predicates.add(criteriaBuilder.equal(root.get("gameId"), gameId));
        }

        return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
    };
}

第 3 步:将 Specification 实例传递给 jpaRepo.findAll(specification),它将返回您的实体对象列表(运行示例中的票证)

ticketRepo.findAll(specification); // Pass output of function in step 2 to findAll