2016-11-03 1 views
8

Lets sagen, dass ich das folgende Repository:Spring Data JPA Repositorys mit Java 8 Streams

public interface UserRepository extends JpaRepository<User, Long> { 

    @Query("select u from User u") 
    Stream<User> streamAllPaged(Pageable pageable); 
} 

Und ich möchte eine Suche durchzuführen:

public Page<User> findAllUsers(Pageable page) { 

    Page<User> page = null; 
    try (Stream<User> users = userRepository.streamAllPaged(page)) { 
      Set<User> users = users.filter(u -> user.getName().equals("foo")) 
        .collect(Collectors.toSet()); 
      //create page from set? 
    } 

} 

Offensichtlich konnte ich eine Unterliste verwenden und manuell einfügen Seitengrößen etc aber ich denke, dass es einen "Standard" Weg geben sollte, dies zu tun?

+1

Ich hätte gedacht 'Collectors.partitioningBy' könnte helfen, aber ohne Zugriff auf eine Position im Stream in nicht sehen, wie. – Aaron

+1

Wenn es Ihnen nichts ausmacht, einen anderen Stream zu verwenden, hat [diese Frage] (http://stackoverflow.com/questions/29273705/how-to-paginate-a-list-of-objects-in-java-8) die Antworten. – Aaron

Antwort

11

Ich würde argumentieren, dass Ihr Anwendungsfall hier nicht zu viel Sinn macht. Wenn Sie mit einem Ergebnis von enden möchten, ist das Starten mit einem Stream nur ineffizient. Sie könnten leicht Ihre erwartete Endergebnis mit diesem erreichen:

public interface UserRepository extends CrudRepository<User, Long> { 

    Page<User> findByName(String name, Pageable pageable); 
} 

Das würde sicherstellen, dass Sie nur die Menge an Namen lesen Sie zunächst fordern. Die Verwendung einer Stream hier untergräbt den Punkt vollständig, da die Filterung auf alleUser Instanzen in den Speicher geladen werden muss, nur um das Prädikat aufzurufen. Sie wollen die Datenbank definitiv so lassen, dass nur die Werte zurückgegeben werden, die an erster Stelle stehen.