/**
SELECT COUNT(*) AS total from table 数据贼多的时候 分页上千,上万,几百万页,明显不实用的分页
不符合需求,但是还要分20页,100页啥的 可以用
* sql拦截器
* @author lure
*/
@Intercepts({
@Signature(type = StatementHandler.class, method ="prepare", args = {Connection.class, Integer.class})
})
@Slf4j
public class TableLimitInterceptorimplements Interceptor {
@Value("${limitNum:12222}")
IntegerlimitNum;
// 拦截器拦截后对象后,执行自己的业务逻辑
@Override
public Objectintercept(Invocation invocation)throws Throwable {
try {
// 入参invocation指拦截到的对象
StatementHandler handler = (StatementHandler) invocation.getTarget();
BoundSql boundSql = handler.getBoundSql();
String sql = boundSql.getSql();
MySqlStatementParser mySqlStatementParser =new MySqlStatementParser(sql);
SQLStatement statement = mySqlStatementParser.parseStatement();
if (statementinstanceof SQLSelectStatement) {
SQLSelect selectQuery = ((SQLSelectStatement) statement).getSelect();
MySqlSelectQueryBlock sqlSelectQuery = (MySqlSelectQueryBlock) selectQuery.getQuery();
String tableName = sqlSelectQuery.getFrom().toString();
SQLLimit limit = sqlSelectQuery.getLimit();
// 拦截 带有limit 并且
if(null == limit && sql.contains("SELECT COUNT(*) AS total")){
String str ="SELECT COUNT(*) AS total";
String newSql = sql.replace(str,"SELECT COUNT(*) AS total from (select 1 ");
newSql = newSql +" limit "+limitNum +" ) as 20220101lure";
// 修改sql
ReflectUtil.setFieldValue(boundSql, "sql", newSql);
}
}
}