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.
|
*
|
* <p>Strategy:
|
* <ul>
|
* <li>SQL WITH WHERE clause -> delegate to parent (normal COUNT(*), indexes help)</li>
|
* <li>SQL WITHOUT WHERE clause -> rewrite to simple SELECT COUNT(*) FROM table,
|
* which lets InnoDB choose the smallest available index for the scan</li>
|
* </ul>
|
*/
|
@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);
|
}
|
}
|