简体   繁体   English

JPQL 查询 select 在与可选搜索参数具有 @OneToMany 关系的实体上

[英]JPQL query for select on entities having @OneToMany relation with optional search parameters

I have two entities, Recipes and Ingredient :我有两个实体, RecipesIngredient

Recipes looks like: Recipes看起来像:

public class Recipes {

    private Long id;

    private String name;

    private Integer serveCount;

    private RecipesType type;

    @OneToMany(mappedBy = "recipes",
            cascade = CascadeType.ALL)
    private List<Ingredient> ingredients = new ArrayList<>();
}

And Ingredient looks like: Ingredient看起来像:

public class Ingredient {
    
        private Long id;

        private String name;

        private Integer count;

        private String unit;

        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "RECIPES_ID", nullable = false)
        private Recipes recipes;
    }

I was asked to implement filtering service with these parameters:我被要求使用这些参数实现过滤服务:

  1. Recipes type(Vegetarian, Dairy, Fast food)食谱类型(素食、乳制品、快餐)
  2. Number of serving份数
  3. Specific ingredients (either include or exclude)具体成分(包括或不包括)

So I created a FilterRequestDTO based on them and implemented my service as below:所以我基于它们创建了一个FilterRequestDTO并实现了我的service ,如下所示:

@Override
public ListResponseDTO<RecipesDTO> getFilteredRecipes(FilterRecipesDTO filterRecipesDTO) {
    ListResponseDTO<RecipesDTO> response = new ListResponseDTO<>();
    var temp = repository.findFilteredRecipes(
            Objects.nonNull(filterRecipesDTO.getType()) ? RecipesType.parseRecipesType(filterRecipesDTO.getType()) : null,
            Objects.nonNull(filterRecipesDTO.getServeCount()) ? filterRecipesDTO.getServeCount() : null,
            filterRecipesDTO.getIncludeIngredients().size() > 0 ? filterRecipesDTO.getIncludeIngredients() : null,
            filterRecipesDTO.getExcludeIngredients().size() > 0 ? filterRecipesDTO.getExcludeIngredients() : null,
            PageRequest.of(filterRecipesDTO.getPage(), filterRecipesDTO.getSize()));

    if (temp.isPresent()) {
        response = new ListResponseDTO<>(filterRecipesDTO.getPage(), temp.get().getNumberOfElements());
        for (Recipes recipes : temp.get().getContent())
            response.getData().add(new RecipesDTO().from(recipes));
    }
    return response;
}

And it calls my Repository method layer which looks like:它调用我的Repository方法层,如下所示:

@Query("select r from Recipes r join Ingredient i on r.id = i.recipes.id " +
        "where (:typ is null or r.type = :typ) " +
        "and (:cnt  is null or r.serveCount = :cnt) " +
        "and (:inc is null or i.name in :inc) " +
        "and (:exc is null or i.name not in :exc)")
Optional<Page<Recipes>> findFilteredRecipes(@Param("typ") RecipesType type,
                                            @Param("cnt") Integer serveCount,
                                            @Param("inc") List<String> includeIngredients,
                                            @Param("exc") List<String> excludeIngredients,
                                            Pageable page);

But when I want to filter result with given includeIngredients and excludeIngredients lists, it does not seem to work.但是当我想用给定的includeIngredientsexcludeIngredients列表过滤结果时,它似乎不起作用。

Do you have any idea how solve this issue?你知道如何解决这个问题吗?

Any help would be appreciated任何帮助,将不胜感激

If you need to return receipt if it contains at least one ingredient requested, the query would be:如果您需要在收据包含至少一种要求的成分时退回收据,查询将是:

select r from Recipes r
where (:typ is null or r.type = :typ)
and (:cnt  is null or r.serveCount = :cnt)
and ((:inc) is null or exists (select 1 from Ingredient i where i.recipes=r and i.name in :inc)) 
and ((:exc) is null or not exists (select 1 from Ingredient i where i.recipes=r and i.name in :exc))

if the requirement is to return receipt with all ingredients requested, the query would be:如果要求返回包含所有要求成分的收据,查询将是:

select r from Recipes r
where (:typ is null or r.type = :typ)
and (:cnt  is null or r.serveCount = :cnt)
and ((:inc) is null or :inccnt = (select count(1) from Ingredient i where i.recipes=r and i.name in :inc)) 
and ((:exc) is null or not exists (select 1 from Ingredient i i.recipes=r and where i.name in :exc))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM