Spring Data Java 8支持

1.概述

Spring Data現在支持Java 8的核心功能,例如OptionalStream 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上獲得示例的完整實現。