2017-07-03 69 views
2

我的产品的实体看起来象下面这样:的Hibernate查询到SQL查询

@Entity 
@Table(name = "order") 

public class OrderEntity { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "order_id") 
    private Long id; 

    @ManyToMany(cascade = CascadeType.ALL) 
    @JoinTable(
     name = "order_products", 
     joinColumns = @JoinColumn(name = "order_id", referencedColumnName = "order_id"), 
     inverseJoinColumns = @JoinColumn(name = "product_id", referencedColumnName = "id") 
    ) 
    private Set<ProductEntity> products = new HashSet<>(); 
} 

ProductEntity:

@Entity 
@Table(name = "product") 
public class ProductEntity { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private long id; 

    @Column(unique = true) 
    private String name; 

    @ManyToMany(mappedBy = "products") 
    private Set<OrderEntity> orders = new HashSet<>(); 
} 

我想获得的所有订单,其中产品名称等于需要的值。并且我编写sql查询以从数据库中获取结果,但我无法为Spring Data JPA编写hibernate查询。

我的PostgreSQL的查询看起来是这样的:

SELECT o.order_id, op.product_id, p.name 
    FROM public.order o 
    INNER JOIN public.order_products op 
    ON p.order_id = op.product_id 
    INNER JOIN public.product p 
    ON op.product_id = p.id 
    WHERE p.name = 'Foo'; 

而这个查询返回我命令,PRODUCT_ID和产品名称的标识。这工作。但我不知道如何使用@Query将这个问题写成spring query。

我需要一个metohod在我的仓库:

@Repository 
public interface OrderRepository extends JpaRepository<OrderEntity, Long> { 
    @Query("") <- place for my query in Hibernate sql 
    List<OrderEntity> findAllByProductName(@Param("name") String name); 
} 
+0

有你阅读文档?该语言被命名为HQL(或JPQL)。不是Hibernate SQL。阅读https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#hql并尝试一些。如果您花时间阅读文档和示例并尝试一下,那么您的查询写起来非常简单。 –

回答

1

试试这个:(它返回完整的OrderEntity对象)

@Query("select o from OrderEntity o join o.products prod where prod.name = :name") 
List<OrderEntity> findAllByProductName(@Param("name") String name); 

,如果你需要急于获取产品的所有数据使用:.... OrderEntityØ加入o.products ...查询,而不是OrderEntityØ加入o.products

1

这是许多entties由列的投影,所以你不得不去的结果类的策略。

基本上,你创建一个POJO类与预期结果的字段的等效构造:

public class ResultClass{ 

    private Integer orderId; 
    private Integer productId; 
    private String name; 

    public ResultClass(Integer orderId, Integer productId, String name){ 
     // set the fields 
    } 
} 

然后你改变查询了一下:

SELECT new com.mypkg.ResultClass(o.order_id, op.product_id, p.name) 
FROM public.order o 
INNER JOIN public.order_products op 
    ON p.order_id = op.product_id 
INNER JOIN public.product p 
    ON op.product_id = p.id 
WHERE p.name = 'Foo'; 

,并更改界面上的返回类型方法:

@Repository 
public interface OrderRepository extends JpaRepository<OrderEntity, Long> { 
    @Query("...") 
    List<ResultClass> findAllByProductName(@Param("name") String name); 
} 
+0

我不明白。我要求查询获取产品名称等于所需价值的所有订单。 – user

+0

嗯......在这种情况下,这确实太无关紧要了......请阅读@JB Nizet指出的文档。但最后如果你想要从多个表中获得列,就像你的问题那么希望我的帖子能派上用场 –

+0

这个答案无论如何都是错误的。您仍在使用SQL查询,而不是JPQL。 –