refactor: 分页查询逻辑优化。

This commit is contained in:
Suomm 2023-06-09 21:01:13 +08:00
parent d20d4cc2d3
commit a69e1e85f0
3 changed files with 44 additions and 132 deletions

View File

@ -652,75 +652,26 @@ public interface BaseMapper<T> {
default <R> Page<R> paginateAs(Page<R> page, QueryWrapper queryWrapper, Class<R> asType, Consumer<FieldQueryBuilder<R>>... consumers) {
List<QueryColumn> selectColumns = CPI.getSelectColumns(queryWrapper);
List<QueryOrderBy> orderBys = CPI.getOrderBys(queryWrapper);
List<Join> joins = CPI.getJoins(queryWrapper);
boolean removedJoins = true;
// 只有 totalRow 小于 0 的时候才会去查询总量
// 这样方便用户做总数缓存而非每次都要去查询总量
// 一般的分页场景中只有第一页的时候有必要去查询总量第二页以后是不需要的
if (page.getTotalRow() < 0) {
//移除 select
CPI.setSelectColumns(queryWrapper, Collections.singletonList(count().as("total")));
//移除 OrderBy
if (CollectionUtil.isNotEmpty(orderBys)) {
CPI.setOrderBys(queryWrapper, null);
}
//移除 left join
if (joins != null && !joins.isEmpty()) {
for (Join join : joins) {
if (!Join.TYPE_LEFT.equals(CPI.getJoinType(join))) {
removedJoins = false;
break;
}
}
} else {
removedJoins = false;
}
if (removedJoins) {
List<String> joinTables = new ArrayList<>();
joins.forEach(join -> {
QueryTable joinQueryTable = CPI.getJoinQueryTable(join);
if (joinQueryTable != null && StringUtil.isNotBlank(joinQueryTable.getName())) {
joinTables.add(joinQueryTable.getName());
}
});
QueryCondition where = CPI.getWhereQueryCondition(queryWrapper);
if (CPI.containsTable(where, CollectionUtil.toArrayString(joinTables))) {
removedJoins = false;
}
}
if (removedJoins) {
CPI.setJoins(queryWrapper, null);
}
queryWrapper = MapperUtil.optimizeCountQueryWrapper(queryWrapper);
long count = selectCountByQuery(queryWrapper);
page.setTotalRow(count);
}
if (page.getTotalRow() == 0 || page.getPageNumber() > page.getTotalPage()) {
if (page.isEmpty()) {
return page;
}
//重置 selectColumns
CPI.setSelectColumns(queryWrapper, selectColumns);
//重置 orderBys
if (CollectionUtil.isNotEmpty(orderBys)) {
CPI.setOrderBys(queryWrapper, orderBys);
}
//重置 join
if (removedJoins) {
CPI.setJoins(queryWrapper, joins);
}
int offset = page.getPageSize() * (page.getPageNumber() - 1);
queryWrapper.limit(offset, page.getPageSize());

View File

@ -1,4 +1,4 @@
/**
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
@ -128,6 +128,10 @@ public class Page<T> implements Serializable {
}
}
public boolean isEmpty() {
return getTotalRow() == 0 || getPageNumber() > getTotalPage();
}
public <R> Page<R> map(Function<? super T, ? extends R> mapper) {
Page<R> newPage = new Page<>();

View File

@ -1,4 +1,4 @@
/**
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
@ -21,11 +21,14 @@ import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.provider.RowSqlProvider;
import com.mybatisflex.core.query.*;
import com.mybatisflex.core.util.CollectionUtil;
import com.mybatisflex.core.util.MapperUtil;
import com.mybatisflex.core.util.StringUtil;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.exceptions.TooManyResultsException;
import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import static com.mybatisflex.core.query.QueryMethods.count;
@ -435,72 +438,26 @@ public interface RowMapper {
List<QueryOrderBy> orderBys = CPI.getOrderBys(queryWrapper);
List<Join> joins = CPI.getJoins(queryWrapper);
boolean removedJoins = true;
// 只有 totalRow 小于 0 的时候才会去查询总量
// 这样方便用户做总数缓存而非每次都要去查询总量
// 一般的分页场景中只有第一页的时候有必要去查询总量第二页以后是不需要的
if (page.getTotalRow() < 0) {
//移除 seelct
CPI.setSelectColumns(queryWrapper, Collections.singletonList(count().as("total")));
//移除 OrderBy
if (CollectionUtil.isNotEmpty(orderBys)) {
CPI.setOrderBys(queryWrapper, null);
}
//移除 left join
if (joins != null && !joins.isEmpty()) {
for (Join join : joins) {
if (!Join.TYPE_LEFT.equals(CPI.getJoinType(join))) {
removedJoins = false;
break;
}
}
} else {
removedJoins = false;
}
if (removedJoins) {
List<String> joinTables = new ArrayList<>();
joins.forEach(join -> {
QueryTable joinQueryTable = CPI.getJoinQueryTable(join);
if (joinQueryTable != null && StringUtil.isNotBlank(joinQueryTable.getName())) {
joinTables.add(joinQueryTable.getName());
}
});
QueryCondition where = CPI.getWhereQueryCondition(queryWrapper);
if (CPI.containsTable(where, CollectionUtil.toArrayString(joinTables))) {
removedJoins = false;
}
}
if (removedJoins) {
CPI.setJoins(queryWrapper, null);
}
queryWrapper = MapperUtil.optimizeCountQueryWrapper(queryWrapper);
long count = selectCountByQuery(schema,tableName, queryWrapper);
page.setTotalRow(count);
}
if (page.getTotalRow() == 0 || page.getPageNumber() > page.getTotalPage()) {
if (page.isEmpty()) {
return page;
}
//重置 selectColumns
CPI.setSelectColumns(queryWrapper, selectColumns);
//重置 orderBys
if (CollectionUtil.isNotEmpty(orderBys)) {
CPI.setOrderBys(queryWrapper, orderBys);
}
//重置 join
if (removedJoins) {
CPI.setJoins(queryWrapper, joins);
}
int offset = page.getPageSize() * (page.getPageNumber() - 1);
queryWrapper.limit(offset, page.getPageSize());