Eta*_*nio 5 java spring querydsl spring-data spring-data-jpa
我正在尝试将QueryDSL与Spring Data JPA一起使用,我想使用findAll分页,但是如果返回类型是a,则总是执行计数List.我不需要这个数,因为它真的很慢,我可以放弃分页的好处.
解决这个问题的方法有哪些
这就是count(),它需要大约30秒的MySQL:
在任何情况下,我都不想重复我需要的每个页面的计数,这个信息只需要第一次调用.
由于QueryDslPredicateExecutor不支持返回Slice作为返回值findAll(Predicate, Pageable),因此Count Query似乎不可避免.但是,您可以定义新的基本存储库接口,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);
}
Run Code Online (Sandbox Code Playgroud)
然后,实现此接口,如:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
基本上,这个实现将获取比请求大小多一个元素并使用结果来构造一个Page.然后,您应该告诉Spring Data将此实现用作存储库基类:
@EnableJpaRepositories(repositoryBaseClass = SliceableRepositoryImpl.class)
Run Code Online (Sandbox Code Playgroud)
最后扩展SliceableRepository为您的基本界面:
public SomeRepository extends SliceableRepository<Some, SomeID> {}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2733 次 |
| 最近记录: |