QueryDSL中有非常方便的分页查询方式
queryDsl.select(...).from(...).where(...).orderBy(...).offset(0).limit(10).fetchResults();
该方法会自动进行一次计数查询,然后根据结果的个数来判断是否还要进行进一步的数据列查询。
想知道Jooq有没有这种快速分页查询的方法可以自动帮我做计数查询和数据列表查询
谢谢!
目前感觉用Jooq做分页查询有些乏味。我需要先构造条件,先根据条件做个计数查询,再用条件做分页查询
var post = Tables.POST;
var postChannel = Tables.POST_CHANNEL;
var postTag = Tables.POST_TAG;
// condition
Condition condition = noCondition();
if (StringUtils.hasText(title)) {
condition = condition.and(post.TITLE.like("%" + title + "%"));
}
if (StringUtils.hasText(reference)) {
condition = condition.and(post.REFERENCE.like("%" + title + "%"));
}
if (enabled != null) {
condition = condition.and(post.ENABLED.eq(enabled));
}
if (publicly != null) {
condition = condition.and(post.PUBLICLY.eq(enabled));
}
if (createAtStart != null || createAtEnd != null) {
condition = condition.and(post.CREATE_AT.between(createAtStart == null
? null : createAtStart.atStartOfDay(),
createAtEnd == null ? null : createAtEnd.atTime(LocalTime.MAX)));
}
if (channelId != null) {
condition = condition.and(exists(selectOne().from(postChannel).where(postChannel.POST_ID.eq(post.ID).and(postChannel.CHANNEL_ID.eq(channelId)))));
}
if (tagId != null) {
condition = condition.and(exists(selectOne().from(postTag).where(postTag.POST_ID.eq(post.ID).and(postTag.TAG_ID.eq(tagId)))));
}
// count
Integer count = ctx.select(count(one())).from(post).where(condition).fetchOne().into(Integer.class);
if (count == 0) {
return Paged.empty();
}
// list
List<PostDTO> ret = ctx.select(post.ID, post.VERSION,post.PREVIEW, post.REFERENCE, post.PATH, post.KEYWORDS,post.TITLE, post.CREATE_AT, post.CREATE_AT, post.ENABLED, post.PUBLICLY, post.TOC, post.POSTER)
.from(post)
.where(condition)
.orderBy(post.CREATE_AT.desc())
.offset(page.offset())
.limit(page.limit())
.fetch(r -> r.into(PostDTO.class))
;
return Paged.of(count, ret);
曾经是QueryDSL的重度用户,现在想试试Jooq。很多事情我可能还没有转念,希望能得到一些指导。谢谢!
想知道Jooq有没有这种快速分页查询的方法可以自动帮我做计数查询和数据列表查询
我不相信 QueryDSL 的便利性可以正确处理所有可能的计算总行数的边缘情况。另见jOOQ 对分页的立场,以及为什么很多程序员都弄错了。
COUNT(*) OVER()
窗口函数 添加到您的查询中即可。鉴于 SQL 中操作的逻辑顺序,窗口函数将在before分页之前进行评估,但在after WHERE
子句中进行评估,因此您可以使用它来获取分页的总行数而无需第二次往返.