package com.core.config; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import lombok.extern.slf4j.Slf4j; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.select.PlainSelect; import net.sf.jsqlparser.statement.select.Select; /** * Optimized pagination interceptor that avoids full-table COUNT queries * for pages without WHERE conditions. * *

Strategy: *

*/ @Slf4j public class FastPaginationInnerInterceptor extends PaginationInnerInterceptor { public FastPaginationInnerInterceptor(DbType dbType) { super(dbType); } @Override public String autoCountSql(IPage page, String sql) { if (!page.optimizeCountSql()) { return super.autoCountSql(page, sql); } try { Statement statement = CCJSqlParserUtil.parse(sql); if (!(statement instanceof Select)) { return super.autoCountSql(page, sql); } Select select = (Select) statement; PlainSelect plainSelect = (PlainSelect) select.getSelectBody(); // If SQL has WHERE conditions, delegate to parent's full COUNT rewriting if (plainSelect.getWhere() != null) { return super.autoCountSql(page, sql); } // No WHERE clause — this is the "browse all records" case. // Return minimal COUNT query so InnoDB picks the smallest index. if (plainSelect.getFromItem() != null) { String tableName = plainSelect.getFromItem().toString(); return "SELECT COUNT(*) FROM " + tableName; } } catch (JSQLParserException e) { log.debug("SQL parsing failed for fast count, using default: {}", e.getMessage()); } return super.autoCountSql(page, sql); } }