优化Spring-Data JPA查询

时间:2013-11-21 12:08:19

标签: java spring-data-jpa

我正在寻找框架生成的查询的可能优化。 据我了解,该过程如下:

  • 您可以将域对象声明为POJO并添加多个注释,例如@Entity@Table@ManyToOne等。

  • 您声明了您的存储库,例如每个接口

使用(2)您可以通过多种方式来描述您的查询:例如:每个方法名称或@Query

如果我写一个像:

这样的查询
@Query("select t from Order t LEFT join fetch t.orderPositions where t.id = ?1")
Page<Order> findById(Pageable pageable, String id);

自动生成SQL查询,其中订单的每一列都被解析,并且顺序地用于订单定位和依赖于obejcts / tables。 好像我写道:

select * from order

因此,如果我需要来自几个连接对象的某些信息,那么查询可能会非常昂贵:而且更有趣的是非常无效。我偶然发现了一个缓慢的查询,MySQL-explain告诉我,在生成的查询中,优化器无法使用索引,这很糟糕。

当然(我知道)我必须处理权衡,生成的 SQL不如手动编写的那样最优,并且具有写入少的优势样板代码。

我的问题是:改善查询,查询执行的好策略是什么?

我自己想过一些选择:

1)是否可以为不同目的定义多个“实体”,例如Order用于访问订单的完整特征,而FilteredOrder更少列而不是Join-columns的分辨率?两者都会引用相同的表,但是一个将使用所有列而另一个只使用一些。

2)使用@Query(... native="true")选择我想要使用的所有列。这样做的好处是,我不会将我的域对象加倍,并且会使用数百个Filtered - 对象丢弃我的代码库。 分页怎么样?将pageable@Query( ...native="true")结合使用仍然可行(恐怕不行)。

3)最后但在我眼中“最差”/样板解决方案:使用JDBCTemplates并在较低级别执行操作。

还有其他选择,我还没有想过? 感谢您对该主题的任何启发:]

更新 我们目前的策略如下

1)如果可能,我使用选择新的 正如我seen,这适用于每个对象(无论是实体还是 POJO

2)结合数据库视图,可以充分利用 SQL ORM 。对于某些用例,可能有兴趣拥有一个聚合结果集。将此结果集定义为视图使得从db-perspective可以轻松地使用简单的 select -statement来查看结果。 对于ORM方,这意味着,您可以轻松定义与此视图匹配的实体,并在顶部获得整个 ORM-goodness :分页包含

2 个答案:

答案 0 :(得分:14)

一种解决方案是使用DTO:

@Query("select new FilteredOrder(o.name, o.size, o.cost) from Order o where o.id = ?1")
Page<FilteredOrder> findFilteredOrderById(Pageable pageable, String id);

如果您想要生成某些报告的实体,您应该考虑使用nosql数据存储区吗?

答案 1 :(得分:2)

看看JPA的懒惰抓取策略。它允许您选择没有关系的对象,但会在您引用它们时获取关系。