Поскольку QueryDslPredicateExecutor
не поддерживает возврат Slice
в качестве возвращаемого значения findAll(Predicate, Pageable)
, поэтому граф запросов кажется неизбежным. Но вы можете определить новый интерфейс базового репозитория и реализовать метод findAll
таким образом, чтобы он не выдавал запрос подсчета для разбивки на страницы. Для начала, вы должны определить интерфейс, который будет использоваться в качестве базового интерфейса для всех остальных Хранилища:
/**
* Interface for adding one method to all repositories.
*
* <p>The main motivation of this interface is to provide a way
* to paginate list of items without issuing a count query
* beforehand. Basically we're going to get one element more
* than requested and form a {@link Page} object out of it.</p>
*/
@NoRepositoryBean
public interface SliceableRepository<T, ID extends Serializable>
extends JpaRepository<T, ID>,
QueryDslPredicateExecutor<T> {
Page<T> findAll(Predicate predicate, Pageable pageable);
}
Затем реализовать этот интерфейс, как:
public class SliceableRepositoryImpl<T, ID extends Serializable>
extends QueryDslJpaRepository<T, ID>
implements SliceableRepository<T, ID> {
private static final EntityPathResolver DEFAULT_ENTITY_PATH_RESOLVER = SimpleEntityPathResolver.INSTANCE;
private final EntityPath<T> path;
private final PathBuilder<T> builder;
private final Querydsl querydsl;
public SliceableRepositoryImpl(JpaEntityInformation<T, ID> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
path = DEFAULT_ENTITY_PATH_RESOLVER.createPath(entityInformation.getJavaType());
this.builder = new PathBuilder<>(path.getType(), path.getMetadata());
this.querydsl = new Querydsl(entityManager, builder);
}
@Override
public Page<T> findAll(Predicate predicate, Pageable pageable) {
int oneMore = pageable.getPageSize() + 1;
JPQLQuery query = createQuery(predicate)
.offset(pageable.getOffset())
.limit(oneMore);
Sort sort = pageable.getSort();
query = querydsl.applySorting(sort, query);
List<T> entities = query.list(path);
int size = entities.size();
if (size > pageable.getPageSize())
entities.remove(size - 1);
return new PageImpl<>(entities, pageable, pageable.getOffset() + size);
}
}
В основном, эта реализация принесла бы еще один элемент, чем запрошенный размер, и использовать результат для построения Page
. Тогда вы должны сказать Spring Data использовать эту реализацию в качестве хранилища базового класса:
@EnableJpaRepositories(repositoryBaseClass = SliceableRepositoryImpl.class)
И, наконец, расширить SliceableRepository
в качестве базового интерфейса:
public SomeRepository extends SliceableRepository<Some, SomeID> {}
Может пожалуйста, поделитесь кодом с нами? Запрос 'count' обычно является частью разбивки на страницы, поэтому вы можете представить количество общих страниц/результатов в пользовательском интерфейсе. Почему в вашем случае часть 'count' замедляется? – miensol