现在我正在使用 JPA。我想知道的是:
我有很多表相互映射。当我查看日志时,我看到在一个简单的查询之后,正在从数据库中提取大量信息。如果一次有很多查询会发生什么?或者它会正常工作吗?如何提高性能?
现在我正在使用 JPA。我想知道的是:
我有很多表相互映射。当我查看日志时,我看到在一个简单的查询之后,正在从数据库中提取大量信息。如果一次有很多查询会发生什么?或者它会正常工作吗?如何提高性能?
如果你真的有很多实体映射在一起,这确实会导致性能问题。如果您有很多@OneToMany
或@ManyToMany
映射,通常会出现这种情况:
@Entity
public class A {
@OneToMany
private List<B> listB;
@ManyToMany
private List<C> listC;
@OneToMany
private List<D> listD;
...
}
但是,您可以做的一件事是使用延迟获取。这意味着字段的加载可能会延迟到第一次访问。您可以通过使用以下fetch
属性来实现此目的:
@Entity
public class A {
@OneToMany(fetch=FetchType.LAZY)
private List<B> listB;
@ManyToMany(fetch=FetchType.LAZY)
private List<C> listC;
@OneToMany(fetch=FetchType.LAZY)
private List<D> listD;
...
}
在上面的示例中,它意味着 listB、listC、listD 在第一次访问列表之前不会从数据库中获取。
延迟获取的具体实现取决于您的 JPA 提供者。
ORM 框架有一个开销。EntityManager
因为它的级别相当高,它有时需要生成大量的原生 SQL 查询,以便在一两行 JPQL 或纯操作中得到你想要的。
但是,JPA 使用两个缓存 - L1 和 L2。一个在实体级别上运行,另一个在 PersistenceUnits 级别上运行。因此,您可能会看到生成了很多 SQL 查询,但一段时间后,您应该会缓存一些数据。
如果您对性能不满意,可以尝试使用延迟加载的集合或自己获取所需的数据(您可能对Bozho 的帖子感兴趣)。
最后,如果您发现缓存没有提高您的性能并且手工制作的 JPQL 查询没有正确完成工作 - 您始终可以恢复为普通 SQL 查询。请注意,这些查询会绕过 JPA 缓存,并且可能需要您在执行本机查询(或在活动事务开始时调用它)之前进行一些刷新。
尽管您将选择优化路线 - 首先在您的环境中对其进行测试,如果您需要此优化,请自行回答。做一些繁重的测试,性能测试等等。
“过早的优化是万恶之源。” D. 克努特