如何为谓词设置连接
How to set join for predicate
我有一个产品实体:
package com.javaschool.entity;
import lombok.*;
import javax.persistence.*;
import java.util.Set;
@EqualsAndHashCode(of = {"id"})
@ToString(of = { "id", "quantity", "price", "model"})
@Entity
@Table(name = "products")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "quantity")
private int quantity;
@Column(name = "price")
private int price;
@Column(name = "model")
private String model;
@Column(name = "is_active")
private boolean active;
@Column(name = "picture_url")
private String url;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "category_id")
private Category category;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "brand_id")
private Brand brand;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "season_id")
private Season season;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "color_id")
private Color color;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "material_id")
private Material material;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "size_id")
private Size size;
@ManyToMany(mappedBy = "productSet", fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private Set<Order> orderSet;
}
我要按品类、季节、颜色、品牌等相关参数筛选
目前我的过滤功能是这样的。它适用于型号、价格、数量等参数。也就是说,对于那些在此 table 中而不是其他人的数据。如何按从其他 table 中获取的参数进行过滤?
@Override
public List<Product> findByParam(List<SearchCriteria> params) {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Product> criteriaQuery = criteriaBuilder.createQuery(Product.class);
Root<Product> root = criteriaQuery.from(Product.class);
Predicate predicate = criteriaBuilder.conjunction();
ProductSearchQueryCriteriaConsumer productConsumer = new ProductSearchQueryCriteriaConsumer(predicate, criteriaBuilder, root);
params.stream().forEach(productConsumer);
predicate = productConsumer.getPredicate();
criteriaQuery.where(criteriaBuilder.equal(root.get(Product_.active), true),
predicate);
List<Product> result = entityManager.createQuery(criteriaQuery).getResultList();
return result;
}
我以为你可以打这样的电话,一切都会好起来的。但是我错了
List<SearchCriteria> params = new ArrayList<SearchCriteria>();
params.add(new SearchCriteria("season_id", ":", "3"));
List<ProductDto> productDtoList = productService.getProductsByParam(params);
我的搜索条件
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SearchCriteria {
private String key;
private String operation;
private Object value;
}
需要做这个:
List<SearchCriteria> params = new ArrayList<SearchCriteria>();
params.add(new SearchCriteria("category", ":", categoryRepository.findById(1)));
也就是在value对象的searchcriteria中,传一个这个class的对象去filter by
我有一个产品实体:
package com.javaschool.entity;
import lombok.*;
import javax.persistence.*;
import java.util.Set;
@EqualsAndHashCode(of = {"id"})
@ToString(of = { "id", "quantity", "price", "model"})
@Entity
@Table(name = "products")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "quantity")
private int quantity;
@Column(name = "price")
private int price;
@Column(name = "model")
private String model;
@Column(name = "is_active")
private boolean active;
@Column(name = "picture_url")
private String url;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "category_id")
private Category category;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "brand_id")
private Brand brand;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "season_id")
private Season season;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "color_id")
private Color color;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "material_id")
private Material material;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "size_id")
private Size size;
@ManyToMany(mappedBy = "productSet", fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private Set<Order> orderSet;
}
我要按品类、季节、颜色、品牌等相关参数筛选
目前我的过滤功能是这样的。它适用于型号、价格、数量等参数。也就是说,对于那些在此 table 中而不是其他人的数据。如何按从其他 table 中获取的参数进行过滤?
@Override
public List<Product> findByParam(List<SearchCriteria> params) {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Product> criteriaQuery = criteriaBuilder.createQuery(Product.class);
Root<Product> root = criteriaQuery.from(Product.class);
Predicate predicate = criteriaBuilder.conjunction();
ProductSearchQueryCriteriaConsumer productConsumer = new ProductSearchQueryCriteriaConsumer(predicate, criteriaBuilder, root);
params.stream().forEach(productConsumer);
predicate = productConsumer.getPredicate();
criteriaQuery.where(criteriaBuilder.equal(root.get(Product_.active), true),
predicate);
List<Product> result = entityManager.createQuery(criteriaQuery).getResultList();
return result;
}
我以为你可以打这样的电话,一切都会好起来的。但是我错了
List<SearchCriteria> params = new ArrayList<SearchCriteria>();
params.add(new SearchCriteria("season_id", ":", "3"));
List<ProductDto> productDtoList = productService.getProductsByParam(params);
我的搜索条件
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SearchCriteria {
private String key;
private String operation;
private Object value;
}
需要做这个:
List<SearchCriteria> params = new ArrayList<SearchCriteria>();
params.add(new SearchCriteria("category", ":", categoryRepository.findById(1)));
也就是在value对象的searchcriteria中,传一个这个class的对象去filter by