業務場景: 一個商品對應多個倉存,須要查詢商品在某個或某幾個庫存中存在時,查詢出來.spring
實體類 ,商品Goodsapp
@Entity @Table(name = "es_goods") public class Goods { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = "goods_id") private Integer id; private String name; //倉庫集合 @OneToMany(mappedBy = "goods", cascade = CascadeType.ALL) private List<ProductStore> productStores; }
實體類,倉庫 ide
@Entity @Table(name = "es_product_store") public class ProductStore { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = "id") private Integer id; //商品 @ManyToOne @JoinColumn(name="goods_id") private Goods goods; //倉庫名,理論上應該使用一個關聯,此處爲了簡便就只用的一個String private String name; }
當使用spring data jpa 的@query簡單查詢時,須要在HQL 中使用 join ui
Repository中的方法spa
// @Query("select g from Goods g where g.productStores.name = ?1 ") 錯誤寫法,啓動報錯 @Query("select DISTINCT g from Goods g left join g.productStores as p where p.name = ?1")//正確 public List<Goods> findGoodsByProductStoreName(String name);
以上是固定查詢時的用法,不少時候咱們使用了Spring data jpa 的動態查詢 即Specification類,此時的業務代碼以下code
new Specification<T>() { @Override public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder) { //話說這方法找了很久很久...若是用尋常path,亦會拋異常 Join join = root.join(root.getModel().getList("productStores", ProductStore.class),JoinType.LEFT); return builder.equeal(join.get("id"),<倉庫id>) } };