Предложение по реализации фильтра поиска с отношением many2many между двумя объектами

#spring #rest #jpa #criteria #specifications

#spring #остальное #jpa #критерии #технические характеристики

Вопрос:

Я хочу реализовать метод поиска rest, который будет фильтровать мой объект Product по заданным параметрам и возвращать мне доступный для просмотра набор продуктов, которые были отфильтрованы.

Я читал об интерфейсе спецификации и API критериев, но у меня возникли трудности с реализацией решения.

Объект Product:

 @Entity
public class Product implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long productId;

    @NotEmpty(message = "The product name must not be null.")
    private String productName;

    private String productDescription;

    @Min(value = 0, message = "The product price must no be less then zero.")
    private double productPrice;

    @Min(value = 0, message = "The product unit must not be less than zero.")
    private int unitInStock;

    @ManyToMany
    @JoinTable(name = "category_product", joinColumns = @JoinColumn(name = "product_id"), inverseJoinColumns = @JoinColumn(name = "category_id"))
    private Set<Category> categories = new HashSet<>();

  

Поскольку я хочу, чтобы пользователь также мог выполнять поиск по названию категории, помимо диапазона цен и unitInStock, который является отдельным объектом и связан с отношением @ManyToMany, я хочу иметь метод, который выглядел бы примерно так:

 
@GetMapping("/search")
    public ResponseEntity<Set<Product>> advancedSearch(@RequestParam(name="category") String categoryName,
                                                       @RequestParam(name="price") double price,
                                                       @RequestParam(name="unitInStock") int unitInStock  ){

    }

  

Объект категории:

 @Entity
public class Category implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long categoryId;

    @NotEmpty(message = "Can not be null")
    private String CategoryName;

    @ManyToMany(mappedBy = "categories")
    @JsonBackReference
    private Set<Product> products = new HashSet<>();

  

Комментарии:

1. Во-первых, Spring предоставляет множество способов реализации отношений «Многие ко многим», таких как «Многие ко многим» с составным классом ключей или «Многие ко многим» с новым объектом. Вам решать, что вы выбрали, исходя из их плюсов и минусов. Во-вторых, когда вы используете JPA, почему бы вам не выбрать JPQL в качестве языка запросов. Это, безусловно, уменьшит ваши усилия по обработке запросов. Спасибо

Ответ №1:

Создайте репозиторий spring с помощью метода с запросом JPQL:

 @Query("select p from Product p left join p.categories c where c.CategoryName like ?1 and p.productPrice=?2 and p.unitInStock=?3")
List<Product> search(String categoryName, double price, int unitInStock)