Spring Data JPA:批量读取大表
简要:
- 如果数据库表很小,则查询数据库方面不需要太多工程。
- 但我们经常使用尺寸太大的表,并且对表的简单查询不起作用并且会破坏一些东西。
- 这是我们需要谨慎编写查询的地方,这样我们就不会影响数据库或应用程序层。
- 在本文中,我们将学习如何查询大型数据库表,而简单的 SELECT 查询将返回大型结果并可能耗尽应用程序内存。
- 使用 Spring Data JPA PageRequest 是迄今为止最好的方法,因为它易于使用且机械性较低。
假设实体是一个简单的帐户表。
@Entity |
账户信息库
对于本练习,我们不需要自己编写任何派生查询,而是可以使用 JPARepository 提供的默认派生查询,因此 AccountRepository 为空。
public interface AccountRepository extends JpaRepository<Account, Integer> {} |
选项 1:使用 PageRequest、JPARepository
这是在 Spring Data JPA 中实现分页的简单且最佳的方法之一。
首先,我们需要创建PageRequest对象
PageRequest pageRequest = PageRequest.of(0,10);
一旦我们有了 PageRequest,我们就可以将它传递给 JPARepository,如下所示,返回类型是 Page。
Page<Account> pageableAccount = accountRepository.findAll(pageRequest);
现在,一旦我们有了页面响应,我们就可以处理它并完成它。为了简洁起见,我们只是将其打印出来。
选项 2:将 TypedQuery 与 StartPosition 和 MaxResults 结合使用
在本例中,我们将使用 TypedQuery 来查询数据库。TypedQuery 对象允许我们设置响应的 startPosition 和 maxResult。
TypedQuery<Account> query = em.createQuery("SELECT a FROM Account a", Account.class); |
通过使用上述设置,可以轻松地以分页方式读取记录。
选项 3:使用PreparedStatement、SQL OFFSET 和 LIMIT 子句
我们可以绕过 JPA 层来获取 JPA Session 对象和查询数据库。
使用 RAW SQL,我们可以设置 OFFSET 和 LIMIT 以返回记录子集,而不是读取整个表。
Session session = em.unwrap(Session.class); |
一旦我们有了包含给定页面结果的 ResultSet,我们就可以像下面这样读取它们:
ResultSet resultSet = preparedStatement.executeQuery(); |