2010-08-17 51 views
3

比方说,我们有:什么是在JPA中选择具有子实体的许多实体的最佳优化方式?

@Entity public class Order { 
    @Id private int id; 
    @OneToMany(mappedBy="order") private List<Item> items; 
    ... 
} 

@Entity public class Item { 
    @Id private int id; 
    @ManyToOne private Order order; 
    ... 
} 

而且,我们说有10.000订单的每一个具有20个项目。

我们需要反复思考所有的订单和他们所有的物品。 在JPA中最好的方法是什么?

我的问题是,如果我只是重复一样的元素:

for (Order order: em.createTypeQuery("select o from Order o", Order.class).getResultList()) { 
    report.printOrder(order); 
    for (Item item: order.getItems()) { 
     report.printOrderItem(item); 
    } 
} 

会造成10.001 SQL查询: 1时间:SELECT * FROM为了 10.000倍:SELECT * FROM项,其中的order_id = ?

有什么办法可以优化它吗?两个查询?一个查询?

(我们使用EclipseLink)

谢谢。

回答

2

您可能还需要考虑的EclipseLink查询提示“eclipselink.batch”与价值“o.items” 。这会导致两个查询,但可以比一次大型的查询更有效。

+0

谢谢。 我刚刚测试过,发现: 1)您可以使用更多的这种类型的提示,如: q.setHint(“eclipselink.batch”,“t.testSurveys”); q.setHint(“eclipselink.batch”,“t.testDefects”); 2)EclipseLink以一种懒惰的方式使用这个批处理提示。它发送秒查询来获取o.items,而不是马上,但是在你调用第一个order.getItems()之后。 – 2010-08-18 07:51:32

0

您可以使用join fetch(这也需要distinct因为join fetchjoin语义):

select distinct o from Order o join fetch o.items 
+0

谢谢。这也有帮助。 但是,在我测试它后:join fetch将这个查询转换成“select o。*,i。* from Order o,Item i where o.id = i.orderId”,这意味着每个项目的结果集都会传输订单的所有字段。这在某些情况下会导致很大的开销。 – 2010-08-18 08:05:22

相关问题