Guardando a SimpleJpaRepository 's findAll(Specification, Pageable)
e readPage(TypedQuery, Pageable, Specification)
metodi. Sembra che l'implementazione di primavera è quello di eseguire sempre una query di conteggio e verificare se lo startIndex è fuori del campo prima di eseguire la query di selezione:
protected Page<T> readPage(TypedQuery<T> query, Pageable pageable, Specification<T> spec) {
query.setFirstResult(pageable.getOffset());
query.setMaxResults(pageable.getPageSize());
Long total = QueryUtils.executeCountQuery(getCountQuery(spec));
List<T> content = total > pageable.getOffset() ? query.getResultList() : Collections.<T> emptyList();
return new PageImpl<T>(content, pageable, total);
}
io non credo che questo è sempre la migliore pratica. Nel mio caso d'uso, ad esempio, siamo felici di eseguire la query di conteggio una volta in primo piano e non nelle chiamate successive perché sappiamo che i nuovi dati non vengono abbastanza frequentemente da giustificare un aggiornamento del conteggio e la query di conteggio è molto costosa da eseguire.
Sarebbe bello se Spring Data fosse in grado di fornire un flag o un metodo alternativo per disabilitare il conteggio per la query sui criteri, simile a simple find queries.
Nel frattempo, ecco la mia soluzione work-around:
Creare una classe interna che le sottoclassi SimpleJpaRepository. Sostituisci readPage per disabilitare la query di conteggio. Crea un DAO, annotalo con @Repository e crea un'istanza di questa classe interna per passare sul EntityManager corretto. Infine, iniettare questo DAO ovunque ricerca "no-count" criteri è applicabile:
@Repository
public class CriteriaNoCountDao {
@PersistenceContext
protected EntityManager em;
public <T, ID extends Serializable> Page<T> findAll(Specification<T> spec, Pageable pageable, Class<T> clazz){
SimpleJpaNoCountRepository<T, ID> noCountDao = new SimpleJpaNoCountRepository<T, ID>(clazz, em);
return noCountDao.findAll(spec, pageable);
}
/**
* Custom repository type that disable count query.
*/
public static class SimpleJpaNoCountRepository<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> {
public SimpleJpaNoCountRepository(Class<T> domainClass, EntityManager em) {
super(domainClass, em);
}
/**
* Override {@link SimpleJpaRepository#readPage(TypedQuery, Pageable, Specification)}
*/
protected Page<T> readPage(TypedQuery<T> query, Pageable pageable, Specification<T> spec) {
query.setFirstResult(pageable.getOffset());
query.setMaxResults(pageable.getPageSize());
List<T> content = query.getResultList();
return new PageImpl<T>(content, pageable, content.size());
}
}
}
possibile duplicato di [? Modo per disattivare interrogazione conteggio da PageRequest per ottenere pagine totali] (http://stackoverflow.com/questions/ 12644749/way-to-disable-count-query-da-pagerequest-per-ottenere-totale-pagine) – mttdbrd
Questo sembra essere risposta qui: http://stackoverflow.com/questions/12644749/way-to-disable- count-query-from-pagerequest-for-getting-total-pages? rq = 1 – mttdbrd
Non proprio. Sto cercando una soluzione per la specifica a.k.a ricerca criteri. Leggendo SimpleJpaRepository.findAll (spec, pageable), sembra che gli implementatori ritengano che una query di conteggio debba sempre essere eseguita per prima e se la slice non è nell'intervallo, non eseguirà la query di selezione. Non credo che la query di conteggio sia sempre meno costosa. –