现象:使用了分页查询,但是查询出来的结果一直没分页效果;
结论:生成查询请求参数page必须使用带参数(当前页,每页大小)的构造方法;
不能直接使用空的构造方法,然后用set方法设置参数
源码分析:(mybatis-plus-support 2.3.1)
1.我们首先来看page类,带了参数的构造方法,会调用supper(current,size)方法
public class Page<T> extends Pagination {
public Page() {
/* 注意,传入翻页参数 */
}
public Page(int current, int size) {
super(current, size);
}
}
2.然后我们来看下Pagination类的构造方法,会发现调用了父类的super(int intNum1,int intNum2)方法
public class Pagination extends RowBounds implements Serializable {
public Pagination(int current, int size) {
this(current, size, true);
}
public Pagination(int current, int size, boolean searchCount) {
this(current, size, searchCount, true);
}
public Pagination(int current, int size, boolean searchCount, boolean openSort) {
super(PageHelper.offsetCurrent(current, size), size);
if (current > 1) {
this.current = current;
}
this.size = size;
this.searchCount = searchCount;
this.openSort = openSort;
}
}
3.接着看下RowBounds这个类,发现是设置了偏移量,offset和limit。那么现在可以得到一个结论:
不带参数的Page的构造方法,偏移量为默认值;带参数的的Page构造方法,会设置偏移量
public class RowBounds {
public static final int NO_ROW_OFFSET = 0;
public static final int NO_ROW_LIMIT = Integer.MAX_VALUE;
public static final RowBounds DEFAULT = new RowBounds();
private final int offset;
private final int limit;
public RowBounds() {
this.offset = NO_ROW_OFFSET;
this.limit = NO_ROW_LIMIT;
}
public RowBounds(int offset, int limit) {
this.offset = offset;
this.limit = limit;
}
public int getOffset() {
return offset;
}
public int getLimit() {
return limit;
}
}
4.然后我们去看下分页拦截器PaginationInterceptor,只需要看intercept的部分代码,会发现当rowBounds为null或者RowBounds为默认值的时候,会被当做无需分页,从而导致分页失效的
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class PaginationInterceptor extends SqlParserHandler implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = (StatementHandler) PluginUtils.realTarget(invocation.getTarget());
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
this.sqlParser(metaObject);
// 先判断是不是SELECT操作
MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) {
return invocation.proceed();
}
RowBounds rowBounds = (RowBounds) metaObject.getValue("delegate.rowBounds");
/* 不需要分页的场合 */
if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {
// 本地线程分页
if (localPage) {
// 采用ThreadLocal变量处理的分页
rowBounds = PageHelper.getPagination();
if (rowBounds == null) {
return invocation.proceed();
}
} else {
// 无需分页
return invocation.proceed();
}
}
}