分享知识 传递快乐

mybatis-plus 处于性能和安全的考虑,默认分页查询的单页最大数量为500,也可以根据需要进行调整,如:

@Configuration
public class MybatisPlusAutoConfigure {

/**
* 单页分页条数限制(默认无限制,参见 插件#handlerLimit 方法)
*/
private static final Long MAX_LIMIT = 1000L;

/**
* 新的分页插件,一缓和二缓遵循mybatis的规则,
* 需要设置 MybatisConfiguration#useDeprecatedExecutor = false
* 避免缓存出现问题(该属性会在旧插件移除后一同移除)
*/
@Bean
public MybatisPlusInterceptor paginationInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

//分页插件: PaginationInnerInterceptor
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
paginationInnerInterceptor.setMaxLimit(MAX_LIMIT);

//防止全表更新与删除插件: BlockAttackInnerInterceptor
BlockAttackInnerInterceptor blockAttackInnerInterceptor = new BlockAttackInnerInterceptor();
interceptor.addInnerInterceptor(paginationInnerInterceptor);
interceptor.addInnerInterceptor(blockAttackInnerInterceptor);

return interceptor;
}
}

但是有时候我们需要突破这个的限制,只需要设置limit的值小于等于0就可了。

虽然是可以解决分页查询突破单页最大500条记录的问题,但是这个是全局的配置,会导致所有的分页都可以突破这个限制,有可能会引发安全或者性能隐患。所以在这里我列举了两种方式:

Mybatis Plus 3.4版本

如果你的服务中使用的是 mybatis plus 3.4版本之后想要突破查询最大记录数的限制非常方便,只需要在Page信息中设置maxLimit的值就可了:

Page<UserEntity> page = new Page<>(pageNum, 1000);
page.setMaxLimit(1000L);

在源码中查看到maxLimit的作用,默认使用Page信息中的maxLimit的值来作为size处理超出分页条数限制,默认归为限制数:

protected void handlerLimit(IPage<?> page) {
long size = page.getSize();
Long pageMaxLimit = page.maxLimit();
Long limit = pageMaxLimit != null ? pageMaxLimit : this.maxLimit;
if (limit != null && limit > 0L && size > limit) {
page.setSize(limit);
}
}

Mybatis Plus 3.3之前版本

如果服务中使用的是 mybatis plus3.3 之前版本突破限制,需要对 PaginationInterceptor 类中的 handlerLimit 方法做修改就可以。

protected void handlerLimit(IPage<?> page) {
page.setSize(this.limit);
}

为了使单页最大500的限制默认生效,还要支持突破限制查询,我重写了Page和PaginationInterceptor 来解决问题。

ExtPage

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

public class ExtPage<T> extends Page<T> {

/**
* 用来判断是否允许超过pageSize max值=500的限制
*/
private boolean isBreachDefaultMaxLimit = false;

public ExtPage() {
}

public ExtPage(boolean isBreachDefaultMaxLimit, long current, long size) {
if (current > 1) {
this.setCurrent(current);
}
this.setSize(size);
this.setTotal(0);
this.setSearchCount(true);
this.isBreachDefaultMaxLimit = isBreachDefaultMaxLimit;
}

public boolean isBreachDefaultMaxLimit() {
return isBreachDefaultMaxLimit;
}

public void setBreachDefaultMaxLimit(boolean breachDefaultMaxLimit) {
isBreachDefaultMaxLimit = breachDefaultMaxLimit;
}
}

ExtPaginationInterceptor

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Signature;

import java.sql.Connection;

@Intercepts({@Signature(
type = StatementHandler.class,
method = "prepare",
args = {Connection.class, Integer.class}
)})
public class ExtPaginationInterceptor extends PaginationInterceptor {

@Override
protected void handlerLimit(IPage<?> page) {
if (page instanceof ExtPage) {
if (((ExtPage<?>) page).isBreachDefaultMaxLimit()) {
return;
}
}
super.handlerLimit(page);
}
}

MybatisPlusAutoConfigure

@Configuration
public class MybatisPlusAutoConfigure {

@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}

@Bean
@Order(0)
public PaginationInterceptor paginationInterceptor2() {
ExtPaginationInterceptor paginationInterceptor = new ExtPaginationInterceptor();
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
}

使用自定义分页 ExtPage 进行查询,当需要突破单页最大500记录限制时 isBreachDefaultMaxLimit 设为true 

@Override
public Page<MsgContentEntity> pageTagByStatus(Integer status, Integer limit, Integer page) {

ExtPage<MsgContentEntity> extPage = new ExtPage<>(true, page, limit);
return msgContentMapper.selectTagsPage(extPage, status);
}

—————————
如有不足请留言指正
相互学习,共同进步