是否可以创建动态 JPQL 查询?

问题描述 投票:0回答:2

我需要创建一个动态查询。我尝试使用 JPQL 来做到这一点,但不能。 例如:

    public List get(String category, String name, Integer priceMin, Integer priceMax){
    List<Prod> list;
    String query = "select p from Prod p where 1<2 ";
    String queryCat="";
    String queryName="";
    String queryPriceMin="";
    String queryPriceMax="";
    String and = " and ";
    if (!category.isEmpty()){
        query+=and+"p.cat.name=:category ";
    }
    if (!name.isEmpty()){
        query+=and+"p.name=:name ";
    }
    if (priceMin!=null){
        query+=and+"p.price>=:priceMin ";

    }
    if (priceMax!=null){
        query+=and+"p.price<=:priceMax ";
    }
    return list = entityManager.createQuery(query)
            .setParameter("category", category)
            .setParameter("name",name)
            .setParameter("priceMin", priceMin)
            .setParameter("priceMax", priceMax)
            .getResultList();
    
}

如果有所有参数,则查询运行,但如果没有这样的参数

category
我有异常
java.lang.IllegalArgumentException: Parameter with that name [category] did not exist
并且我明白为什么会这样,但如何避免这个问题?

java jpa jpql
2个回答
21
投票

你可以尝试一下。

    public List<Prod> get(String category, String name, Integer priceMin, Integer priceMax){
    Map<String, Object> paramaterMap = new HashMap<String, Object>();
    List<String> whereCause = new ArrayList<String>();

    StringBuilder queryBuilder = new StringBuilder();
    queryBuilder.append("select p from Prod p ");

    if (!category.isEmpty()){
        whereCause.add(" p.cat.name =:category ");
        paramaterMap.put("category", category);
    }
    if (!name.isEmpty()){
        whereCause.add(" p.name =:name ");
        paramaterMap.put("name", name);
    }
    if (priceMin!=null){
        whereCause.add(" p.price>=:priceMin ");
        paramaterMap.put("priceMin", priceMin);
    }
    if (priceMax!=null){
        whereCause.add("p.price<=:priceMax  ");
        paramaterMap.put("priceMax", priceMax);
    }

    //.................
    queryBuilder.append(" where " + StringUtils.join(whereCause, " and "));
    Query jpaQuery = entityManager.createQuery(queryBuilder.toString());

    for(String key :paramaterMap.keySet()) {
            jpaQuery.setParameter(key, paramaterMap.get(key));
    }

    return  jpaQuery.getResultList();

}

0
投票

您可以使用JpaSpecificationExecutor 我会用我的例子来解释。

  • 在存储库中

     public interface ABCRepository extends JpaRepository<ABC, UUID> , JpaSpecificationExecutor<Event> {
    

    }

  • 在 Service 方法中,您可以按如下方式使用它


公共列表搜索(EventSearch eventSearch) {

        return eventRepository.findAll(new Specification<Event>(){
            @Override
            public Predicate toPredicate(Root<Event> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if(!eventSearch.getTitle().equals(null)) {
                    predicates.add(criteriaBuilder.like(root.get("title"), "%" + eventSearch.getTitle() + "%"));
                }

            if(!eventSearch.getLocation().equals(null)) {
                predicates.add(criteriaBuilder.like(root.get("location"), "%" + eventSearch.getLocation() + "%"));
            }

            if(!eventSearch.getStartDate().equals(null)){
                predicates.add(criteriaBuilder.greaterThan(root.get("startDate"), eventSearch.getStartDate()));
            }

            if(!eventSearch.getEndDate().equals(null)){
                predicates.add(criteriaBuilder.greaterThan(root.get("endDate"), eventSearch.getEndDate()));
            }

            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        }
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.