Spring Data Java 8支持
1.概述
Spring Data現在支持Java 8的核心功能,例如Optional
, Stream
API和CompletableFuture
。
在這篇快速的文章中,我們將介紹一些如何在框架中使用它們的示例。
2. Optional
讓我們從CRUD存儲庫方法開始-現在將結果包裝在Optional
:
public interface CrudRepository<T, ID> extends Repository<T, ID> {
Optional<T> findById(ID id);
}
返回Optional
實例時,這很有用,提示該值可能不存在。有關可選的更多信息,請參見此處。
現在我們要做的就是將返回類型指定為Optional
:
public interface UserRepository extends JpaRepository<User, Integer> {
Optional<User> findOneByName(String name);
}
3. Stream
API
Spring Data還提供對Java 8最重要功能之一的支持- Stream
API。
過去,只要我們需要返回多個結果,就需要返回一個集合:
public interface UserRepository extends JpaRepository<User, Integer> {
// ...
List<User> findAll();
// ...
}
這種實現方式的問題之一是內存消耗。
我們必須急於加載並將所有檢索到的對象保留在其中。
我們可以利用分頁來改進:
public interface UserRepository extends JpaRepository<User, Integer> {
// ...
Page<User> findAll(Pageable pageable);
// ...
}
在某些情況下,這就足夠了,但在另一些情況下,由於檢索數據所需的大量請求,分頁實際上是行不通的。
感謝Java 8 Stream
API和JPA提供程序–現在,我們可以定義我們的存儲庫方法僅返回對象Stream
:
public interface UserRepository extends JpaRepository<User, Integer> {
// ...
Stream<User> findAllByName(String name);
// ...
}
Spring Data使用特定於提供程序的實現來流式傳輸結果(Hibernate使用ScrollableResultSet
,EclipseLink使用ScrollableCursor
)。它減少了內存消耗和對數據庫的查詢調用。因此,它比前面提到的兩個解決方案要快得多。
使用Stream
處理數據需要我們在完成Stream
關閉Stream
。
可以通過在Stream
上調用close()
方法或使用try-with-resources
:
try (Stream<User> foundUsersStream
= userRepository.findAllByName(USER_NAME_ADAM)) {
assertThat(foundUsersStream.count(), equalTo(3l));
我們還必須記住在事務中調用存儲庫方法。否則,我們將得到一個例外:
org.springframework.dao.InvalidDataAccessApiUsageException
:您正在嘗試執行流查詢方法而沒有周圍事務來保持連接打開,從而可以實際使用Stream
。確保使用流的代碼使用@Transactional
或其他任何聲明(只讀)事務的方式。
4. CompletableFuture
Spring Data存儲庫可以在Java 8的CompletableFuture
**和Spring機制的支持下異步運行,以**執行異步方法:
@Async
CompletableFuture<User> findOneByStatus(Integer status);
調用此方法的客戶端將立即返回future,但是一個方法將在另一個線程中繼續執行。
有關CompletableFuture
處理的更多信息,請參見此處。
5.結論
在本教程中,我們展示了Java 8功能如何與Spring Data一起使用。
可以在Github上獲得示例的完整實現。