如何在规范方法中使用多个参数来过滤对象?

huangapple go评论89阅读模式
英文:

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&lt;Coffee&gt; getCoffeesByRoasting(String name) {
        return (root, query, criteriaBuilder) -&gt; {
            Join&lt;Object, Object&gt; roastingJoin = root.join(Coffee_.ROASTING);
            return criteriaBuilder.equal(roastingJoin.get(Roasting_.NAME), name);
        };
    }}

Service:

public PageDTO&lt;DrinkDTO&gt; findAllFilter(int page, int pageSize, String roastingName, String coffeeType) {

        PageRequest pageRequest = PageRequest.of(page, pageSize, Sort.by(&quot;price&quot;).ascending());

        final Page&lt;Coffee&gt; coffees = coffeeRepository
                .findAll(CoffeeSpecification.getCoffeesByRoasting(roastingName), pageRequest);

        return new PageDTO&lt;&gt;(drinkMapper.drinksToDrinksDTO(coffees));
    }

Controller:

@GetMapping(&quot;/coffees&quot;)
    public PageDTO&lt;DrinkDTO&gt; getAllCoffees(@RequestParam(value = &quot;page&quot;, defaultValue = &quot;1&quot;) int page,
                                           @RequestParam(value = &quot;page_size&quot;, defaultValue = &quot;5&quot;) int pageSize,
                                           @RequestParam String roastingName) {

        return coffeeService.findAllFilter(page, pageSize, roastingName, coffeeType);
    }

答案1

得分: 1

我已经使用了JpaSpecification来基于mobilepincode进行区域过滤,并使用以下代码来实现相同的功能:

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&lt;UserAreaMapping&gt; userAreaMappingByFilter(String pinCode, String mobile) {
        return (Specification&lt;UserAreaMapping&gt;) (root, query, cb) -&gt; {
            Predicate pinCodePredicate = Objects.nonNull(pinCode) ? cb.equal(root.get(&quot;pinCode&quot;), pinCode) : cb.conjunction();
            Predicate mobilePredicate = Objects.nonNull(mobile) ? cb.equal(root.get(&quot;mobile&quot;), 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&lt;Coffee&gt; getCoffeesByRoasting(String name, String type) {
        return (root, query, criteriaBuilder) -&gt; {
            Join&lt;Object, Object&gt; roastingJoin = root.join(Coffee_.ROASTING);
            Join&lt;Object, Object&gt; 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.

huangapple
  • 本文由 发表于 2020年7月31日 21:41:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/63192998.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定