[英]JPQL query for select on entities having @OneToMany relation with optional search parameters
I have two entities, Recipes
and Ingredient
:我有两个实体,
Recipes
和Ingredient
:
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:我被要求使用这些参数实现过滤服务:
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.但是当我想用给定的
includeIngredients
和excludeIngredients
列表过滤结果时,它似乎不起作用。
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.