【问题标题】:How to filter on input parameters only using Jpa Specification?如何仅使用 Jpa 规范过滤输入参数?
【发布时间】:2020-08-02 11:32:19
【问题描述】:

我正在写一个在线商店来购买咖啡和茶。我使用Spring-Boot (MVC)、HibernateJPAPostgreSQL。在应用程序中,我将有一个过滤器,在这里我将按parameters 过滤搜索(例如,茶颜色、茶类型等)。我为此使用了Spring-Data-Jpa Specification。我写了一个工作正常并完成它的工作的方法。当我通过所有三个parameters 时,它会为我过滤列表并仅提供适合的饮料。但是如果用户没有传递过滤器中的所有参数怎么办。如果它只根据茶的颜色过滤怎么办?那该怎么办?或许你应该使用if-else,但究竟如何?

饮料类:

@Inheritance(strategy = InheritanceType.JOINED)
public class Drink {

    // Fields
    //
    private @Id
    @GeneratedValue
    Long id;

    private String name;

    private BigDecimal price;

    private String about;

    @Column(name = "is_deleted")
    private boolean isDeleted;

    // Relationships
    //
    @ManyToOne
    @JoinColumn(name = "packaging_id")
    private Packaging packaging;

    @ManyToOne
    @JoinColumn(name = "manufacturer_id")
    private Manufacturer manufacturer;

    @ManyToOne
    @JoinColumn(name = "country_id")
    private Countries countries;
}

茶课:

public class Tea extends Drink {

    // Relationships
    //
    @ManyToOne
    @JoinColumn(name = "type_id")
    private TeaType teaType;

    @ManyToOne
    @JoinColumn(name = "color_id")
    private TeaColor teaColor;
}

规格:

public class TeaSpecification {

    public static Specification<Tea> getTeasByFilter(Long colorId, Long typeId, Long countryId) {
        return (root, query, criteriaBuilder) -> {
            Predicate colorPredicate = criteriaBuilder
                    .equal(root.get(Tea_.teaColor).get(TeaColor_.id), colorId);
            Predicate typePredicate = criteriaBuilder
                    .equal(root.get(Tea_.teaType).get(TeaType_.id), typeId);
            Predicate countryPredicate = criteriaBuilder
                    .equal(root.get(Tea_.countries).get(Countries_.id), countryId);
            return criteriaBuilder.and(colorPredicate, typePredicate, countryPredicate);
        };
    }

服务:

    /**
     *
     * @param page
     * @param pageSize
     * @param colorId
     * @param typeId
     * @param countryId
     * @return filtered Coffees(DTOs)
     */
    public PageDTO<DrinkDTO> findAllByFilter(int page, int pageSize, Long colorId,
                                             Long typeId, Long countryId) {

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

        final Page<Tea> teas = teaRepository
                .findAll(TeaSpecification.getTeasByFilter(colorId, typeId, countryId), pageRequest);

        return new PageDTO<>(drinkMapper.drinksToDrinksDTO(teas));
    }

【问题讨论】:

    标签: java spring-mvc parameters spring-data-jpa specifications


    【解决方案1】:

    正如你所说,使用 if 可以完成这项工作。因此,如果每个谓词不为空,则将它们添加到列表中。

    然后只需执行以下操作:

    List<Predicate> predicates = new ArrayList<>();
    
    // here your conditionals to create/add the predicates
    
    
    Predicate query = criteriaBuilder.and(predicates.toArray(new Predicate[0]));
    return criteriaBuilder.and(query);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-11
      • 2023-01-15
      • 2019-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多