2014-11-03 123 views
5

我正嘗試使用從數據庫檢索到的對象列表創建新的Page。首先,我從數據庫中獲取所有元素,將其轉換爲Stream,然後使用lambda篩選結果。然後,我需要一個帶有一組元素的頁面,但是,實例化一個新的PageImpl似乎沒有返回具有正確大小的頁面。Spring Data PageImpl沒有返回正確大小的頁面?

這裏是我的代碼:

List<Produtos> listaFinal; 
Stream<Produtos> stream = produtosRepository.findAll().stream(); 
listaFinal = stream.filter(p -> p.getProdNome().contains("uio")).collect(Collectors.toList()); 

long total = listaFinal.size(); 
Page<Produtos> imp = new PageImpl<>(listaFinal,pageable,total); 

下面是調試截圖:

注意在可分頁對象的大小設置爲20,它知道它需要4頁渲染70個元素,但它返回整個列表。

我錯過了什麼?

編輯回答托馬斯提出的意見:

我知道如何使用頁面返回只是一個數據的切片。我展示的代碼是我嘗試使用lambda表達式來過濾我的集合。對我來說問題是我想用Java 8的lambda來通過Spring Data JPA查詢數據庫。我習慣VB.NET和實體function(x)查詢表達式,並想知道如何做到這一點與Spring JPA。

在我的倉庫,進出口使用extends JpaRepository<Produtos, Integer>, QueryDslPredicateExecutor<Produtos>這使我獲得findAll(Predicate,Pageable)。但是,謂詞不是輸入的,所以我不能在查詢中簡單地使用p -> p.getProdNome().contains("uio")。我正在使用SQL Server和Hibernate。

回答

4

在瞭解了有關Spring Data如何工作的更多信息之後,我最終在我的JpaRepository實現內部的方法上使用了@Query註釋,以正確查詢數據庫並篩選結果,從而消除了使用流然後轉換回頁面的需要。

下面是上面的代碼看起來的情況下,任何人都需要一個例子:

@Query("select p from Produtos p where p.prodNome = ?1") 
public Page<Produtos> productsListByName(String prodNome, Pageable pageable) 

林意識到Spring的findBy方法,但有時該方法的名字變成真的很難根據參數的量,所以我只需要讀取堅持JPQL。

這樣做,頁面的內容總是會達到您在Spring配置中定義的最大元素數量。

我還使用了一個自定義實現PageImpl,我現在不在工作,無法訪問代碼,但我會盡可能地發佈它。

編輯:自定義實現可以發現here

+0

不錯!我會用我正在做的事情給我一個機會。 – stites 2015-10-04 03:31:18

+0

您可以向我提供您用於PageImpl的代碼嗎?我現在面臨同樣的問題! – user3127109 2016-06-15 10:10:09

+0

已添加代碼。請注意,在我的情況下需要執行此實現,因爲我正在處理REST服務,並且默認實現對我來說不起作用,在您的情況下可能會有所不同。 – dubonzi 2016-06-23 14:11:24

2

如果我理解您的代碼正確的,那麼你的意圖是加載數據庫中的所有記錄,並把它們分割成被收集在PageImpl X水桶,對不對?

那不是它以前的工作方式。在PageablePage抽象的真實意圖是不具有查詢所有數據,但所需要的數據只是「切片」 。

在你的情況,你可以通過Page<X> page = repository.findAll(pageable);查詢數據並簡單地返回。 頁面包含當前頁面的記錄以及一些附加信息,例如記錄總數和是否有下一頁。

在客戶端代碼,你可以使用這些信息來呈現的記錄,並適當地產生下一個/上鍊接的列表。 請注意,結果類型爲Page<X>的查詢發出2個查詢(1確定查詢的總計數,1確定實際頁面數據)。

如果您不需要關於結果總數的信息,但仍然希望能夠生成下一個鏈接,則應該使用 作爲返回類型 - 因爲它只發出1個查詢。

+0

我編輯了我的原始問題與我的評論,因爲它太長了寫在這裏,請看看請!謝謝。 – dubonzi 2014-11-04 19:05:11

+0

我面臨同樣的問題。我必須使用DTO來映射查詢的輸出以刪除一些隱藏的列。所以我首先得到所有的結果,然後根據DTO將結果映射到新的輸出。然後對新結果使用PageImpl。但它顯示所有記錄而不是分頁信息。 – 2015-07-01 17:04:54

2

PageImpl不打算執行任何種類列表的分頁的。 From the docs你可以看到它只是「基本的Page實現」,它幾乎聽起來像你想要的,但它確實是誤導人的。

使用PagedListHolder這是一個簡單的狀態持有人處理對象列表,將它們分離成頁面。

0

要延長stite's answer,一個PagedListHolder是要走的路,這裏是如何:

List<String> list = // ... 

// creation 
PagedListHolder page = new PagedListHolder(list); 
page.setPageSize(10); // number of items per page 
page.setPage(0); // set to first page 

// retrieval 
page.getPageCount(); // number of pages 
page.getPageList(); // a List which represents the current page 

如果需要排序,使用另一個PagedListHolder constructorMutableSortDefinition