Spring data jpa @OneToMany 在一的一端进行查询()对集合属性设置条件查询)
业务场景: 一个商品对应多个仓存,需要查询商品在某个或某几个库存中存在时,查询出来.
实体类 ,商品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>) } };