Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring Jpa服务调用与Jpa查询_Java_Spring_Jpa - Fatal编程技术网

Java Spring Jpa服务调用与Jpa查询

Java Spring Jpa服务调用与Jpa查询,java,spring,jpa,Java,Spring,Jpa,我是一名春季Jpa初学者。我脑子里有个虫子。我想知道: -处理服务类中的所有业务并多次调用Jpa存储库,该存储库只包含CRUD、getList等基本操作 Vs -在Jpa存储库中进行长查询。通常,您总是需要调用单个查询Jpa存储库,只需选择需要修改的对象。然后可以直接使用检索到的对象的方法从中加载数据并修改检索到的对象。查询未加载的数据将在对象需要时自动加载 例如,您可以加载一个人并修改其联系地址,如下所示: Person person = personRepository.find(perso

我是一名春季Jpa初学者。我脑子里有个虫子。我想知道:
-处理服务类中的所有业务并多次调用Jpa存储库,该存储库只包含CRUD、getList等基本操作
Vs

-在Jpa存储库中进行长查询。

通常,您总是需要调用单个查询Jpa存储库,只需选择需要修改的对象。然后可以直接使用检索到的对象的方法从中加载数据并修改检索到的对象。查询未加载的数据将在对象需要时自动加载

例如,您可以加载一个人并修改其联系地址,如下所示:

Person person = personRepository.find(personId);
for (Address address : person.getAddresses()) {
  if ("CONTACT_ADDRESS".equals(address.getType()) {
    address.setCity("London");
  }
}
检索所有必要的数据,并将所有修改保存到数据库中

尽管这是简单明了的,但有时您可能会遇到性能问题,特别是当您只需要加载一个地址而不是所有地址时。或者,如果您总是需要所有地址,并希望在单个查询中与person一起加载它们

然后,在存储库中引入新的优化查询是一个很好的解决方案。例如,一个查询,它将使用
获取连接加载所有地址,并且在您遍历地址时不需要额外的惰性(自动)查询来加载它们:

@Query("select distinct u from User u left join fetch u.addresses where u.id = ?")
public List<User> findWithAddresses(Long id);
@Query(“从用户u中选择不同的u left join获取u.addresses,其中u.id=?”)
公共列表findWithAddresses(长id);

除了切换
findWithAddresses()
的方法
find()
外,这不需要更改上述代码。但是后台只执行一个SQL查询,而不是多个SQL查询。

第一个SQL查询没有意义。用户已经有地址,您只需调用
User.getAddresses()
。第二个也没有多大意义。查询中的左连接完全没有用处。如果希望该查询在单个查询中加载用户及其地址(并且不依赖延迟加载来获取地址),则该查询必须是
选择与用户u不同的u left join fetch u.addresses,其中u.id=:id
。首先,如果是延迟加载,该怎么办?我无法通过调用
user.getAddresses()
获取地址。为什么我需要这里的
不同的
?这张单子总是与众不同的。跳过这个例子,问题是:在我的例子中,它是否相同,我指的是它打开数据库连接的次数,查询和代理访问的次数。延迟加载并不意味着“地址永远不会被加载”。这意味着“地址将在您需要时加载”。因此,是的,调用user.getAddresses().size()将执行另一个查询来加载地址,填充用户的地址列表,然后返回用户的地址数。需要使用distinct,因为否则,如果用户有3个地址,您将得到一个包含3个用户的列表,而不是一个包含1个用户的列表。“地址将在您需要时加载”谢谢,请在我的机器上进行测试。“需要使用distinct,因为否则,如果用户有3个地址,您将得到3个用户的列表,而不是1个用户的列表。”我想,
user
Onetomany
Address
关系将返回一个列表,其中
user
包含一个列表
Address
。另请参见我的更新以了解修改的示例,具体取决于。如果通过小查询代码更容易阅读和维护,并且速度足够快,那么就使用它。否则,用另一个。是的!这就是我要找的。顺便问一下,您知道什么时候从连接池借用到数据库的连接吗?何时释放连接?连接通常在事务期间分配,因此在事务开始时“借用”,在提交或回滚时释放。但我不确定,因为这是特定于实现的,entitymanager可能会保留分配的连接直到关闭,但这相当愚蠢。