Issue
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);
}
Solution
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.
Answered By - Vipul Kumar