領先一步
VMware 提供培訓和認證,以加速您的進展。
了解更多Spring Data 的 CrudRepository
具有多種方法,可以傳回由 repository 管理的實體的複數實例。它透過使用 Iterable
而非 List
來達成,如同人們可能預期的那樣。在許多情況下,這並不重要,因為您通常無論如何都想迭代結果。然而,您偶爾可能偏好 List
。在這些情況下,Iterable
就令人感到困擾。
我將撰寫更多關於最初為何做出此選擇,以及在您使用 Spring Data 2.x 期間如何處理它的文章。然而,先讓我發布好消息
Spring Data 3.0.0 現在在最新的快照版本中提供了 ListCrudRepository
,它在 CrudRepository
傳回 Iterable
的地方傳回 List
。
範例 1. CrudRepository 與 ListCrudRepository 的比較
@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
<S extends T> S save(S entity);
<S extends T> Iterable<S> saveAll(Iterable<S> entities);
Optional<T> findById(ID id);
boolean existsById(ID id);
Iterable<T> findAll();
Iterable<T> findAllById(Iterable<ID> ids);
long count();
void deleteById(ID id);
void delete(T entity);
void deleteAllById(Iterable<? extends ID> ids);
void deleteAll(Iterable<? extends T> entities);
void deleteAll();
}
@NoRepositoryBean
public interface ListCrudRepository<T, ID> extends CrudRepository<T, ID> {
<S extends T> List<S> saveAll(Iterable<S> entities);
List<T> findAll();
List<T> findAllById(Iterable<ID> ids);
}
廣受歡迎的 PagingAndSortingRepository
過去是從 CrudRepository
擴展而來,但現在已不再如此。這讓您可以將其與 CrudRepository
或 ListCrudRepository
或您自己建立的基礎介面結合使用。這表示您現在必須明確地從 CRUD 片段擴展,即使您已經從 PagingAndSortingRepository
擴展也是如此。
範例 2. 分頁和排序 repository — 2.x 版本
public interface PersonRepository<Person, Long> extends PagingAndSortingRepository<Person, Long> {}
範例 3. 分頁和排序 repository — 3.x 版本
public interface PersonRepository<Person, Long> extends PagingAndSortingRepository<Person, Long>, ListCrudRepository<Person, Long> {}
還有其他介面會傳回 Iterable<T>
,現在也獲得了傳回 List<T>
的配套介面。
片段介面傳回 Iterable
新的片段介面傳回 List
QuerydslPredicateExecutor
ListQuerydslPredicateExecutor
QueryByExampleExecutor
ListQueryByExampleExecutor
此外,與 PagingAndSortingRepository
類似,其他排序 repository 介面過去會擴展其各自的 CRUD 變體,但現在已不再如此。
排序片段介面
它不再擴展的 CRUD repository
ReactiveSortingRepository
CoroutineSortingRepository
CoroutineCrudRepository
Rx3JavaSortingRepository
這表示,當您使用這些介面中的任何一個作為 Spring Data repository 的基礎時,您現在需要額外擴展各自的 CRUD repository(假設您實際上對使用它的 CRUD 功能感興趣)。
如果您尚未準備好跳到 3.0.0 快照版本,您仍然可以使用所有現有的選項來避免處理 Iterable
作為傳回值的情況。
您不需要擴展 CrudRepository
。您可以改用 Repository
,它沒有任何方法。現在您可以僅新增您實際想要的方法,並使用您想要的傳回類型。如果它們與 CrudRepository
中的類型相符,但傳回 Collection
或 List
而非 Iterable
,Spring Data 會為您處理轉換。此外,在大多數情況下,您可能實際上不需要在生產環境中使用 deleteAll
,對吧?
如果您想要 CrudRepository
的所有方法,但希望將 Iterable
替換為其他內容,您可以透過擴展 CrudRepository
並覆寫您想要變更的方法來實現。
為了避免在您宣告的每個 repository 介面中都執行此操作,您可以建立您自己的基礎 repository 介面。對於這種方法,請使用與上述相同的方法,但使用 @NoRepositoryBean
進行註解,以便 Spring Data 不會嘗試為其建立實作。您實際的 repository 介面現在可以從此介面擴展。廣受歡迎的 JpaRepository
就是這樣一個介面。
與上述方法相同,您可以使用 Streamable
作為傳回類型,它是一個 Iterable
,但提供直接轉換方法為 Stream
、List
和 Set
。
如果您不想修改 repository,您可以使用 Streamable
從 Iterable
轉換為 Stream
、List
或 Set
的介面。
CrudRepository
的方法需要由每個 Spring Data 實作來實作。因此,它不僅是 Spring Data 使用者的 API,也是提供 Spring Data 模組的人員的 SPI。此外,這樣的模組可能不想在傳回之前填滿完整的列表,而是希望快速傳回 Iterable
,同時仍在載入和處理資料。
如果 CrudRepository
傳回 List
,您將無法覆寫其方法以傳回 Streamable
、Set
、Collection
或 Iterable
。
Streamable
本來會是一個很棒的傳回類型,因為它結合了彈性和可用性。不幸的是,它會將 Spring 介面強加於您的領域模型中,這被許多人認為是不可接受的,或至少是一種程式碼異味。
此外,一旦 Iterable
出現,就變得難以甚至不可能在不破壞現有程式碼的情況下變更 API。因此,找到一個具有更好可用性,同時限制變更造成的破壞的解決方案花費了一些時間。
我們希望您喜歡這個解決方案,並且我們相信您會讓我們知道您的想法。