首页 > 技术文章 > Spring data jpa @OneToMany 在一的一端进行查询()对集合属性设置条件查询)

java-arthur 2019-07-08 08:59 原文

业务场景: 一个商品对应多个仓存,需要查询商品在某个或某几个库存中存在时,查询出来.

实体类 ,商品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>)
        
    }
};

 

推荐阅读