英文:
How to filter an object using multiple parameters in the specification method?
问题
我正在使用 Spring-Boot
(MVC
) 和 Hibernate
编写在线商店。我决定使用 Jpa specification
来过滤对象的列表。例如,使用 烘焙程度 和 咖啡类型 参数来过滤咖啡。我按照所有的指南进行操作,一切都正常,但只有一个输入参数,即烘焙程度。请告诉我如何添加一个或多个参数用于过滤...
例如,我的实现:
public class CoffeeSpecification {
public static Specification<Coffee> getCoffeesByRoasting(String name) {
return (root, query, criteriaBuilder) -> {
Join<Object, Object> roastingJoin = root.join(Coffee_.ROASTING);
return criteriaBuilder.equal(roastingJoin.get(Roasting_.NAME), name);
};
}
}
服务(Service):
public PageDTO<DrinkDTO> findAllFilter(int page, int pageSize, String roastingName, String coffeeType) {
PageRequest pageRequest = PageRequest.of(page, pageSize, Sort.by("price").ascending());
final Page<Coffee> coffees = coffeeRepository
.findAll(CoffeeSpecification.getCoffeesByRoasting(roastingName), pageRequest);
return new PageDTO<>(drinkMapper.drinksToDrinksDTO(coffees));
}
控制器(Controller):
@GetMapping("/coffees")
public PageDTO<DrinkDTO> getAllCoffees(@RequestParam(value = "page", defaultValue = "1") int page,
@RequestParam(value = "page_size", defaultValue = "5") int pageSize,
@RequestParam String roastingName) {
return coffeeService.findAllFilter(page, pageSize, roastingName, coffeeType);
}
英文:
I am writing an online-store using Spring-Boot
(MVC
) and Hiberbate
. I decided to use the Jpa specification
to filter the list of objects. For example, filter coffee with parameters of roast and type of coffee. I did all the guide and everything worked for me, but with only one input parameter, roasting. How to add one or more parameters for the filter, please tell me...
For example my realisation:
public class CoffeeSpecification {
public static Specification<Coffee> getCoffeesByRoasting(String name) {
return (root, query, criteriaBuilder) -> {
Join<Object, Object> roastingJoin = root.join(Coffee_.ROASTING);
return criteriaBuilder.equal(roastingJoin.get(Roasting_.NAME), name);
};
}}
Service:
public PageDTO<DrinkDTO> findAllFilter(int page, int pageSize, String roastingName, String coffeeType) {
PageRequest pageRequest = PageRequest.of(page, pageSize, Sort.by("price").ascending());
final Page<Coffee> coffees = coffeeRepository
.findAll(CoffeeSpecification.getCoffeesByRoasting(roastingName), pageRequest);
return new PageDTO<>(drinkMapper.drinksToDrinksDTO(coffees));
}
Controller:
@GetMapping("/coffees")
public PageDTO<DrinkDTO> getAllCoffees(@RequestParam(value = "page", defaultValue = "1") int page,
@RequestParam(value = "page_size", defaultValue = "5") int pageSize,
@RequestParam String roastingName) {
return coffeeService.findAllFilter(page, pageSize, roastingName, coffeeType);
}
答案1
得分: 1
我已经使用了JpaSpecification
来基于mobile
和pincode
进行区域过滤,并使用以下代码来实现相同的功能:
public class UserAreaMappingSpecifications {
public static Specification<UserAreaMapping> userAreaMappingByFilter(String pinCode, String mobile) {
return (Specification<UserAreaMapping>) (root, query, cb) -> {
Predicate pinCodePredicate = Objects.nonNull(pinCode) ? cb.equal(root.get("pinCode"), pinCode) : cb.conjunction();
Predicate mobilePredicate = Objects.nonNull(mobile) ? cb.equal(root.get("mobile"), mobile) : cb.conjunction();
return cb.and(pinCodePredicate, mobilePredicate);
};
}
}
我使用了谓词并使用AND运算符将它们组合在一起。
可能的话,您也可以使用您的实现,如下所示:
public class CoffeeSpecification {
public static Specification<Coffee> getCoffeesByRoasting(String name, String type) {
return (root, query, criteriaBuilder) -> {
Join<Object, Object> roastingJoin = root.join(Coffee_.ROASTING);
Join<Object, Object> typeJoin = root.join(Coffee_.TYPE);
Predicate roastingPredicate = criteriaBuilder.equal(roastingJoin.get(Roasting_.NAME), name);
Predicate typePredicate = criteriaBuilder.equal(roastingJoin.get(Roasting_.TYPE), type);
return cb.and(roastingPredicate, typePredicate);
};
}
}
希望我能够解决您的问题。
注意: 根据您的需求,您可以使用or()
运算符而不是使用and()
运算符。
英文:
I have used JpaSpecification
for filtering area based on mobile
and pincode
and using the following code to achieve the same
public class UserAreaMappingSpecifications {
public static Specification<UserAreaMapping> userAreaMappingByFilter(String pinCode, String mobile) {
return (Specification<UserAreaMapping>) (root, query, cb) -> {
Predicate pinCodePredicate = Objects.nonNull(pinCode) ? cb.equal(root.get("pinCode"), pinCode) : cb.conjunction();
Predicate mobilePredicate = Objects.nonNull(mobile) ? cb.equal(root.get("mobile"), mobile) : cb.conjunction();
return cb.and(pinCodePredicate, mobilePredicate);
};
}
}
I have used predicates and combining them using and operator.
Possibly, you can also do with your implementation as well
public class CoffeeSpecification {
public static Specification<Coffee> getCoffeesByRoasting(String name, String type) {
return (root, query, criteriaBuilder) -> {
Join<Object, Object> roastingJoin = root.join(Coffee_.ROASTING);
Join<Object, Object> typeJoin = root.join(Coffee_.TYPE);
Predicate rostingPredicate = criteriaBuilder.equal(roastingJoin.get(Roasting_.NAME), name);
Predicate typePredicate = criteriaBuilder.equal(roastingJoin.get(Roasting_.TYPE), type);
return cb.and(rostingPredicate, typePredicate);
};
}}
Hope I was able to solve your problem.
Note: You can use or()
operator based on your requirement instead of using and()
operator.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论