2013-03-05 9 views
7

Ho una tabella di grandi dimensioni a cui vorrei accedere tramite un archivio dati Spring.Come gestire un ampio set di dati utilizzando i Data Reporter di Spring?

Attualmente, sto cercando di estendere l'interfaccia PagingAndSortingRepository ma sembra che posso solo definire metodi che restituiscono liste, ad es .:

public interface MyRepository extends 
     PagingAndSortingRepository<MyEntity, Integer> 
{ 
    @Query(value="SELECT * ...") 
    List<MyEntity> myQuery(Pageable p); 
} 

D'altra parte, il metodo findAll() che viene fornito con PagingAndSortingRepository rendimenti un Iterable (e suppongo che i dati non siano caricati in memoria).

È possibile definire query personalizzate che restituiscono anche Iterable e/o non caricano tutti i dati in memoria in una sola volta?

Esistono alternative per la gestione di tavoli di grandi dimensioni?

+0

'List' implementa l'interfaccia' Iterable', quindi il metodo di query personalizzato restituisce un 'Iterable'. – zagyi

+0

Suppongo che Spring Data non carichi tutto in memoria quando utilizzo findAll(), ho sbagliato? Modificherò la domanda. –

+0

[implementazione sottostante] (https://github.com/SpringSource/spring-data-jpa/blob/master/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java#L247) recupera semplicemente un elenco, quindi non è così sofisticato. – zagyi

risposta

9

Abbiamo la risposta di consulenza classica qui: dipende. Poiché l'implementazione del metodo è specifica del negozio, dipendiamo dall'API del negozio sottostante. In caso di JPA non è possibile fornire l'accesso allo streaming come ….getResultList() restituisce un List. Quindi esponiamo anche il al client, in quanto gli sviluppatori JPA potrebbero essere utilizzati per lavorare con gli elenchi. Quindi per JPA l'unica opzione è usare l'API di impaginazione.

Per un negozio come Neo4j supportiamo l'accesso allo streaming poiché i repository restituiscono Iterable sui metodi CRUD e sull'esecuzione dei metodi finder.

+0

Ciao Oliver, grazie per la spiegazione. Ho creato un Iterable per astrarre il materiale di impaginazione. Se hai un po 'di tempo, apprezzerei davvero qualsiasi feedback sul codice/approccio. Grazie ancora :) https://gist.github.com/josericardo/5102304 –

+1

In genere raccomando di non fare cose come queste.È facile consegnare un wrapper che recupera in modo invisibile i dati, ma ti imbatterai in tutti i tipi di problemi, in quanto non hai il controllo sul limite della sessione, quindi esegui "LazyLoadingException". Cosa c'è di sbagliato nell'accedere a 'Pagina', iterando sul contenuto e ripeterlo se' Page.hasNext() 'è' true'? Questo almeno rende ovvio che ottieni i limiti della sessione a livello di repository, a meno che non ti trovi in ​​una transazione con ambito più ampio. –

+0

Grazie per il feedback e il tempo :) –

2

Il implementation di findAll() carica semplicemente l'intero elenco di tutte le entità in memoria. Il suo tipo di ritorno Iterable non implica che implementa una sorta di gestione del cursore a livello di database.

D'altra parte il tuo metodo personalizzato myQuery(Pageable) caricherà solo un valore di una pagina di entità, poiché l'implementazione generata rispetta il suo parametro Pageable. È possibile dichiarare il tipo di reso come Page o List. In quest'ultimo caso, si riceve comunque lo stesso numero (limitato) di entità, ma non i metadati che un Page porta in aggiunta.

Quindi, in pratica, hai fatto la cosa giusta per evitare di caricare tutte le entità in memoria nella tua query personalizzata.

Rivedere lo related documentation here.

+0

Il secondo link è rotto. Ora è https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.special-parameters – kolobok

Problemi correlati