在将一些遗留代码从 QueryDSL 3.x 转换到 5.x 之前,我仍在学习 QueryDSL。我有这个代码:
query = query.distinct()
.from(qCamera)
.where()
.orderBy(order)
.limit( pageSize )
.offset((long) pageNum * pageSize );
List<Tuple> datatuple = query.list( a whole ton of fields)
long totalResults = query.count();
显然这有很多问题。但现在,我需要了解如何使用
limit()
和 offset()
,同时返回整个记录计数,以便我们也可以实现分页。
我可以在原始查询上使用
fetchCount()
并获取整个大小吗?或者还有什么我必须做的吗?
我不知道我要发布的内容是否是最好的方法,但它对我有用。这是一个示例项目,它似乎可以工作。
总之,我在
buildBookQuery()
中准备了基本查询。然后,我克隆查询并更改选择,如您所见。然后在 runBookQuery()
中,我在获取之前添加了一个 order-by 以及 limit 和 offset 调用。
我不知道这是否是最佳方式。我相当确定这会导致对数据库的两次点击。
SELECT count(*)
通常但并不总是很快。
如果还有其他方法可以做到这一点,我希望有人发布更好的方法。
public List<BookInfo> pagedBookInfo(int pageSize, int pageNumber) {
System.out.printf("pagedBookInfo(%d,%d)\n", pageSize, pageNumber);
JPAQuery<Tuple> query = buildBookQuery();
long size = query.clone().select(QBook.book.count()).fetchFirst();
System.out.printf("Full length: %d\n", size);
query = query.offset( pageSize * pageNumber ).limit(pageSize);
return runBookQuery(query);
}
/**
* This is how you a join when you want to select data from both tables.
* The important part is the sequence of
* .select().from().innerJoin().on().
*/
JPAQuery<Tuple> buildBookQuery(
JPAQueryFactory queryFactory = new JPAQueryFactory(JPQLTemplates.DEFAULT, entityManager);
QMember member = QMember.member;
QBook book = QBook.book;
JPAQuery<Tuple> query = queryFactory
.select(member.id, member.name, book.title)
.from(member)
.innerJoin(book)
.on(book.in(member.books))
;
return query;
}
/**
* This is how you execute a Tuple-based query and
* return consolidated results.
*/
ArrayList<BookInfo> runBookQuery(JPAQuery<Tuple> query) {
OrderSpecifier<?> byName = new OrderSpecifier<>(com.querydsl.core.types.Order.ASC, QMember.member.name);
OrderSpecifier<?> byTitle = new OrderSpecifier<>(com.querydsl.core.types.Order.ASC, QBook.book.title);
query.orderBy(byName, byTitle);
List<Tuple> results = query
.fetchJoin()
.fetch();
ArrayList<BookInfo> list = new ArrayList<>();
for (Tuple tuple: results) {
BookInfo bi = new BookInfo();
bi.memberName = tuple.get(1, String.class);
bi.title = tuple.get(2, String.class);
list.add(bi);
}
return list;
}