optimize Page.java

This commit is contained in:
开源海哥 2023-06-19 17:03:32 +08:00
parent 5ab1d43731
commit ba43579c68
5 changed files with 119 additions and 198 deletions

View File

@ -676,7 +676,7 @@ public interface BaseMapper<T> {
// 一般的分页场景中只有第一页的时候有必要去查询总量第二页以后是不需要的 // 一般的分页场景中只有第一页的时候有必要去查询总量第二页以后是不需要的
if (page.getTotalRow() < 0) { if (page.getTotalRow() < 0) {
QueryWrapper countQueryWrapper; QueryWrapper countQueryWrapper;
if (page.isOptimizeCountSql()) { if (page.needOptimizeCountQuery()) {
countQueryWrapper = MapperUtil.optimizeCountQueryWrapper(queryWrapper); countQueryWrapper = MapperUtil.optimizeCountQueryWrapper(queryWrapper);
} else { } else {
countQueryWrapper = MapperUtil.rawCountQueryWrapper(queryWrapper); countQueryWrapper = MapperUtil.rawCountQueryWrapper(queryWrapper);
@ -688,7 +688,7 @@ public interface BaseMapper<T> {
return page; return page;
} }
queryWrapper.limit(page.getOffset(), page.getPageSize()); queryWrapper.limit(page.offset(), page.getPageSize());
List<R> records; List<R> records;
if (asType != null) { if (asType != null) {

View File

@ -1,169 +0,0 @@
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.core.paginate;
import java.io.Serializable;
import java.util.List;
/**
* 分页接口
*
* @param <T> 数据类型
* @author 王帅
* @since 2023-06-18
*/
public interface IPage<T> extends Serializable {
/**
* 获取当前页码
*
* @return 页码
*/
int getPageNumber();
/**
* 设置当前页码
*
* @param pageNumber 页码
*/
void setPageNumber(int pageNumber);
/**
* 获取当前每页数据数量
*
* @return 每页数据数量
*/
int getPageSize();
/**
* 设置当前每页数据数量
*
* @param pageSize 每页数据数量
*/
void setPageSize(int pageSize);
/**
* 获取数据总数
*
* @return 数据总数
*/
long getTotalRow();
/**
* 设置数据总数
*
* @param totalRow 数据总数
*/
void setTotalRow(long totalRow);
/**
* 获取当前页的数据
*
* @return 当前页的数据
*/
List<T> getRecords();
/**
* 设置当前页的数据
*
* @param records 当前页的数据
*/
void setRecords(List<T> records);
/**
* 获取当前分页偏移量
*
* @return 偏移量
*/
default int getOffset() {
return getPageSize() * (getPageNumber() - 1);
}
/**
* 是否自动优化 COUNT 查询语句默认优化
*
* @return {@code true} 优化{@code false} 不优化
*/
default boolean isOptimizeCountSql() {
return true;
}
/**
* 设置是否自动优化 COUNT 查询语句
*
* @param optimizeCountSql 是否优化
*/
default void setOptimizeCountSql(boolean optimizeCountSql) {
// 默认总是优化
}
/**
* 获取总页数
*
* @return 总页数
*/
default long getTotalPage() {
// 实时计算总页数
int pageSize = getPageSize();
if (pageSize == 0) {
return 0L;
}
long totalRow = getTotalRow();
long totalPage = totalRow / pageSize;
if (totalRow % pageSize != 0) {
totalPage++;
}
return totalPage;
}
/**
* 设置总页数
*
* @param totalPage 总页数
*/
default void setTotalPage(long totalPage) {
// 总页数是实时计算的所以这里设置了也没用
}
/**
* 是否存在上一页
*
* @return {@code true} 存在上一页{@code false} 不存在上一页
*/
default boolean hasPrevious() {
return getPageNumber() > 1;
}
/**
* 是否存在下一页
*
* @return {@code true} 存在下一页{@code false} 不存在下一页
*/
default boolean hasNext() {
return getPageNumber() < getTotalPage();
}
/**
* 当前页是否为空
*
* @return {@code true} 空页{@code false} 非空页
*/
default boolean isEmpty() {
return getTotalRow() == 0 || getPageNumber() > getTotalPage();
}
}

View File

@ -15,12 +15,18 @@
*/ */
package com.mybatisflex.core.paginate; package com.mybatisflex.core.paginate;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.function.Function; import java.util.function.Function;
public class Page<T> implements IPage<T> { /**
* 分页对象
*
* @param <T> 对象类型
*/
public class Page<T> implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public static final int INIT_VALUE = -1; public static final int INIT_VALUE = -1;
@ -31,7 +37,7 @@ public class Page<T> implements IPage<T> {
private long totalPage = INIT_VALUE; private long totalPage = INIT_VALUE;
private long totalRow = INIT_VALUE; private long totalRow = INIT_VALUE;
private boolean optimizeCountSql = true; private boolean optimizeCountQuery = true;
public static <T> Page<T> of(int pageNumber, int pageSize) { public static <T> Page<T> of(int pageNumber, int pageSize) {
return new Page<>(pageNumber, pageSize); return new Page<>(pageNumber, pageSize);
@ -56,7 +62,6 @@ public class Page<T> implements IPage<T> {
this.setTotalRow(totalRow); this.setTotalRow(totalRow);
} }
public Page(List<T> records, int pageNumber, int pageSize, long totalRow) { public Page(List<T> records, int pageNumber, int pageSize, long totalRow) {
this.setRecords(records); this.setRecords(records);
this.setPageNumber(pageNumber); this.setPageNumber(pageNumber);
@ -65,22 +70,22 @@ public class Page<T> implements IPage<T> {
} }
@Override
public boolean isOptimizeCountSql() {
return optimizeCountSql;
}
@Override /**
public void setOptimizeCountSql(boolean optimizeCountSql) { * 获取当前页的数据
this.optimizeCountSql = optimizeCountSql; *
} * @return 当前页的数据
*/
@Override
public List<T> getRecords() { public List<T> getRecords() {
return records; return records;
} }
@Override
/**
* 设置当前页的数据
*
* @param records 当前页的数据
*/
public void setRecords(List<T> records) { public void setRecords(List<T> records) {
if (records == null) { if (records == null) {
records = Collections.emptyList(); records = Collections.emptyList();
@ -88,12 +93,21 @@ public class Page<T> implements IPage<T> {
this.records = records; this.records = records;
} }
@Override /**
* 获取当前页码
*
* @return 页码
*/
public int getPageNumber() { public int getPageNumber() {
return pageNumber; return pageNumber;
} }
@Override
/**
* 设置当前页码
*
* @param pageNumber 页码
*/
public void setPageNumber(int pageNumber) { public void setPageNumber(int pageNumber) {
if (pageNumber < 1) { if (pageNumber < 1) {
throw new IllegalArgumentException("pageNumber must greater than or equal 1current value is: " + pageNumber); throw new IllegalArgumentException("pageNumber must greater than or equal 1current value is: " + pageNumber);
@ -102,12 +116,21 @@ public class Page<T> implements IPage<T> {
} }
@Override /**
* 获取当前每页数据数量
*
* @return 每页数据数量
*/
public int getPageSize() { public int getPageSize() {
return pageSize; return pageSize;
} }
@Override
/**
* 设置当前每页数据数量
*
* @param pageSize 每页数据数量
*/
public void setPageSize(int pageSize) { public void setPageSize(int pageSize) {
if (pageSize < 0) { if (pageSize < 0) {
throw new IllegalArgumentException("pageSize must greater than or equal 0current value is: " + pageSize); throw new IllegalArgumentException("pageSize must greater than or equal 0current value is: " + pageSize);
@ -116,22 +139,39 @@ public class Page<T> implements IPage<T> {
this.calcTotalPage(); this.calcTotalPage();
} }
@Override /**
* 获取数据总数
*
* @return 数据总数
*/
public long getTotalPage() { public long getTotalPage() {
return totalPage; return totalPage;
} }
@Override /**
* 设置总页数
*
* @param totalPage 总页数
*/
public void setTotalPage(long totalPage) { public void setTotalPage(long totalPage) {
this.totalPage = totalPage; this.totalPage = totalPage;
} }
@Override /**
* 获取数据总数
*
* @return 数据总数
*/
public long getTotalRow() { public long getTotalRow() {
return totalRow; return totalRow;
} }
@Override
/**
* 设置数据总数
*
* @param totalRow 数据总数
*/
public void setTotalRow(long totalRow) { public void setTotalRow(long totalRow) {
this.totalRow = totalRow; this.totalRow = totalRow;
this.calcTotalPage(); this.calcTotalPage();
@ -148,17 +188,67 @@ public class Page<T> implements IPage<T> {
} }
} }
@Override
/**
* 当前页是否为空
*
* @return {@code true} 空页{@code false} 非空页
*/
public boolean isEmpty() { public boolean isEmpty() {
return getTotalRow() == 0 || getPageNumber() > getTotalPage(); return getTotalRow() == 0 || getPageNumber() > getTotalPage();
} }
@Override
/**
* 是否存在下一页
*
* @return {@code true} 存在下一页{@code false} 不存在下一页
*/
public boolean hasNext() { public boolean hasNext() {
return getTotalPage() != 0 && getPageNumber() < getTotalPage(); return getTotalPage() != 0 && getPageNumber() < getTotalPage();
} }
/**
* 是否存在上一页
*
* @return {@code true} 存在上一页{@code false} 不存在上一页
*/
public boolean hasPrevious() {
return getPageNumber() > 1;
}
/**
* 获取当前分页偏移量
*
* @return 偏移量
*/
public int offset() {
return getPageSize() * (getPageNumber() - 1);
}
/**
* 设置是否自动优化 COUNT 查询语句
*
* @param optimizeCountQuery 是否优化
*/
public void setOptimizeCountQuery(boolean optimizeCountQuery) {
this.optimizeCountQuery = optimizeCountQuery;
}
/**
* 是否自动优化 COUNT 查询语句默认优化
*
* @return {@code true} 优化{@code false} 不优化
*/
public boolean needOptimizeCountQuery() {
return optimizeCountQuery;
}
public <R> Page<R> map(Function<? super T, ? extends R> mapper) { public <R> Page<R> map(Function<? super T, ? extends R> mapper) {
Page<R> newPage = new Page<>(); Page<R> newPage = new Page<>();
newPage.pageNumber = pageNumber; newPage.pageNumber = pageNumber;

View File

@ -441,7 +441,7 @@ public interface RowMapper {
// 一般的分页场景中只有第一页的时候有必要去查询总量第二页以后是不需要的 // 一般的分页场景中只有第一页的时候有必要去查询总量第二页以后是不需要的
if (page.getTotalRow() < 0) { if (page.getTotalRow() < 0) {
QueryWrapper countQueryWrapper; QueryWrapper countQueryWrapper;
if (page.isOptimizeCountSql()) { if (page.needOptimizeCountQuery()) {
countQueryWrapper = MapperUtil.optimizeCountQueryWrapper(queryWrapper); countQueryWrapper = MapperUtil.optimizeCountQueryWrapper(queryWrapper);
} else { } else {
countQueryWrapper = MapperUtil.rawCountQueryWrapper(queryWrapper); countQueryWrapper = MapperUtil.rawCountQueryWrapper(queryWrapper);
@ -453,7 +453,7 @@ public interface RowMapper {
return page; return page;
} }
queryWrapper.limit(page.getOffset(), page.getPageSize()); queryWrapper.limit(page.offset(), page.getPageSize());
page.setRecords(selectListByQuery(schema, tableName, queryWrapper)); page.setRecords(selectListByQuery(schema, tableName, queryWrapper));

View File

@ -144,7 +144,7 @@ class UserMapperTest {
.leftJoin(ROLE).as("r").on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID)); .leftJoin(ROLE).as("r").on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID));
System.err.println(queryWrapper.toSQL()); System.err.println(queryWrapper.toSQL());
Page<UserVO> page = Page.of(1, 1); Page<UserVO> page = Page.of(1, 1);
page.setOptimizeCountSql(false); page.setOptimizeCountQuery(false);
int pageNumber = 0; int pageNumber = 0;
do { do {
page.setPageNumber(page.getPageNumber() + 1); page.setPageNumber(page.getPageNumber() + 1);