我对Spring,JPA和Hibernate完全不熟悉,如果我没有正确地解决这个问题,请道歉。
我已经使用这些具有多个性能问题的框架获得了应用程序。
我做了大量搜索但无济于事 - 可能是因为我无法正确地表达我的问题。
该场景(简而言之)当通过EntityManager执行一个sql语句时,它依次调用结果集的每一行的相关查询。 在我的情况下,一个sql语句可能会导致数百(在某些情况下成千上万)相关的sql语句被调用 - 杀死我们的服务器。
一个人为的例子,可能是:
public class Job
{
public long jobId;
public String name;
public List<Transaction> transactions;
}
public class Transaction
{
public long transactionId
public List<Stock> stocks;
}
public class Stock
{
public long stockId;
public String name;
}
The code uses a statement like:
String jpaQuery = "select distinct j from Job j where j.jobId = :jobId order by name asc";
Query query = entityManager.createQuery(jpaQuery);
//set parameters...
//This will return a List<Job>, containing lists of Transaction and Stock objects
return query.getResultList();
执行这个单个sql语句会导致执行多个sql语句(可以在tomcat log / eclipse控制台中查看),因此代码/框架会调用它们。 EntityManager尚未扩展,因此框架正在开展工作。
现在我的问题 - 感谢您阅读此...
在Spring,JPA和Hibernate中,处理此问题的最佳方法是什么,因此对数据库的一次调用会返回所需的对象,而不会向数据库发出多个请求?
我想到一种方法是让单个sql语句调用一个存储过程,它可以返回多个结果集,也可以只返回一个包含所有相关对象数据的结果集,并让框架完成剩下的工作(实例化相关的对象)。
我不知道如何在Spring / JPA / Hibernate环境中解决这个问题。 请问有人请给我一些资源,这些资源会给我一些如何处理这个问题的例子/想法吗?还是要搜索的关键字?
版本: Spring:3.0.6。发布 Hibernate:3.5.0-Beta-2
非常感谢 史蒂夫
答案 0 :(得分:1)
首先,这不是一个SQL语句,它是一个JPQL语句,这是一个巨大的差异(不是语法,但逻辑上明智)。
其次,多个SQL语句的原因是从作业到交易再到库存的一对多关系(它被称为N+1 problem)。根据您的使用情况,您可以将关系更改为lazy loading。这意味着,只有在需要对象时才会加载它们。但是,如果处理不当,这可能会导致其他问题。您也可以尝试使用Join Fetching。这将使用连接创建单个查询,而不是在集合中为每个元素发出一个子选择。