業務場景: 一個商品對應多個倉存,需要查詢商品在某個或某幾個庫存中存在時,查詢出來.
實體類 ,商品Goods
@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; }
實體類,倉庫
@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
Repository中的方法
// @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類,此時的業務代碼如下
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>) } };