diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/paginate/PaginateInterceptor.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/paginate/PaginateInterceptor.java deleted file mode 100644 index 0c025b4c..00000000 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/paginate/PaginateInterceptor.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com). - *
- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *
- * http://www.apache.org/licenses/LICENSE-2.0 - *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.mybatisflex.core.paginate;
-
-import com.mybatisflex.core.dialect.LimitOffsetProcessor;
-import com.mybatisflex.core.query.QueryWrapper;
-import org.apache.ibatis.cache.CacheKey;
-import org.apache.ibatis.executor.Executor;
-import org.apache.ibatis.mapping.BoundSql;
-import org.apache.ibatis.mapping.MappedStatement;
-import org.apache.ibatis.mapping.ResultMap;
-import org.apache.ibatis.plugin.Interceptor;
-import org.apache.ibatis.plugin.Intercepts;
-import org.apache.ibatis.plugin.Invocation;
-import org.apache.ibatis.plugin.Signature;
-import org.apache.ibatis.session.ResultHandler;
-import org.apache.ibatis.session.RowBounds;
-
-import java.sql.SQLException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * 分页拦截器。
- *
- * @author 王帅
- * @since 2023-05-18
- */
-@Intercepts({
- @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
- @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class})
-})
-@SuppressWarnings({"rawtypes", "unchecked"})
-public class PaginateInterceptor implements Interceptor {
-
- /**
- * 拦截 Executor 的两个 query 方法,实现分页操作。
- * {@link Executor#query(MappedStatement, Object, RowBounds, ResultHandler)}
- * {@link Executor#query(MappedStatement, Object, RowBounds, ResultHandler, CacheKey, BoundSql)}
- */
- @Override
- public Object intercept(Invocation invocation) throws Throwable {
- // 获取 Executor 对象 query 方法的参数列表
- Object[] args = invocation.getArgs();
- // 获取两个 query 方法都有的参数
- MappedStatement ms = (MappedStatement) args[0];
- Object parameters = args[1];
- RowBounds rowBounds = (RowBounds) args[2];
- ResultHandler resultHandler = (ResultHandler) args[3];
- // 获取 Executor 对象
- Executor executor = (Executor) invocation.getTarget();
-
- BoundSql boundSql;
-
- // 两个 query 方法参数不相同,获取 BoundSql 的方式不同
- if (args.length == 4) {
- // 4 个参数时
- boundSql = ms.getBoundSql(parameters);
- } else {
- // 6 个参数时
- boundSql = (BoundSql) args[5];
- }
-
- // 获取拦截查询方法是否有 Page 参数
- Page page = getPage(parameters);
- // 没有 Page 参数就认为不是分页操作
- if (page == null) {
- return invocation.proceed();
- }
-
- // 设置分页数据
- page.setRecords(executeQuery(executor, ms, parameters, rowBounds, resultHandler, boundSql, page));
- // 设置数据总数量
- page.setTotalRow(executeCount(executor, ms, parameters, rowBounds, resultHandler, boundSql));
-
- return Collections.singletonList(page);
- }
-
- /**
- * 查询被拦截方法的参数有没有 {@link Page} 对象。
- */
- private Page getPage(Object parameters) {
- if (parameters != null) {
- if (parameters instanceof Map) {
- Map, ?> parameterMap = (Map, ?>) parameters;
- for (Entry entry : parameterMap.entrySet()) {
- if (entry.getValue() instanceof Page) {
- return (Page) entry.getValue();
- }
- }
- } else if (parameters instanceof Page) {
- return (Page) parameters;
- }
- }
- return null;
- }
-
- /**
- * 根据 {@link Page} 对象中页码({@link Page#getPageNumber()})
- * 和每页显示的数量({@link Page#getPageSize()}),构建 SQL 语句,
- * 查询指定页的内容。
- */
- private List executeQuery(Executor executor, MappedStatement ms,
- Object parameters, RowBounds rowBounds,
- ResultHandler resultHandler, BoundSql boundSql,
- Page page) throws SQLException {
- // 获取分页 SQL 语句
- String pageSqlStr = getPageSqlStr(boundSql.getSql(), page);
- // 构建分页查询 BoundSql 对象
- BoundSql pageSql = new BoundSql(ms.getConfiguration(), pageSqlStr, boundSql.getParameterMappings(), parameters);
- // 将原 SQL 中的占位符对应的参数,添加到新分页 SQL 中
- boundSql.getAdditionalParameters().forEach(pageSql::setAdditionalParameter);
- // 获取 CacheKey 对象
- CacheKey cacheKey = executor.createCacheKey(ms, parameters, rowBounds, pageSql);
- // 执行分页 SQL 查询数据
- return executor.query(ms, parameters, rowBounds, resultHandler, cacheKey, pageSql);
- }
-
- /**
- * 构建分页 SQL 语句。
- */
- private String getPageSqlStr(String originalSql, Page page) {
- int size = page.getPageSize();
- int number = page.getPageNumber();
- int limitRows = (number - 1) * size;
- return LimitOffsetProcessor.MYSQL.process(new StringBuilder(originalSql), QueryWrapper.create(), size, limitRows).toString();
- }
-
- /**
- * 查询符合原 SQL 条件的数据数量。
- */
- private Long executeCount(Executor executor, MappedStatement ms,
- Object parameters, RowBounds rowBounds,
- ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
- // 获取 count 查询的 MappedStatement 对象
- MappedStatement countMs = getCountMappedStatement(ms);
-
- BoundSql countSql;
-
- if (countMs != null) {
- countSql = countMs.getBoundSql(parameters);
- } else {
- // 获取不到则构建新的 MappedStatement 对象
- countMs = buildCountMappedStatement(ms);
- // 获取 count 查询 SQL
- String countSqlStr = getCountSqlStr(boundSql.getSql());
- // 构建 count 查询 BoundSql 对象
- countSql = new BoundSql(ms.getConfiguration(), countSqlStr, boundSql.getParameterMappings(), parameters);
- // 将原 SQL 中的占位符对应的参数,添加到新 count 查询 SQL 中
- boundSql.getAdditionalParameters().forEach(countSql::setAdditionalParameter);
- }
-
- // 获取 CacheKey 对象
- CacheKey countKey = executor.createCacheKey(countMs, parameters, rowBounds, countSql);
- // 执行 count 查询 SQL 查询数量
- Object result = executor.query(countMs, parameters, rowBounds, resultHandler, countKey, countSql);
- // 处理结果,返回总数量
- return ((Number) ((List) result).get(0)).longValue();
- }
-
- /**
- * 尝试获取已经存在的 {@link MappedStatement} 对象。
- */
- private MappedStatement getCountMappedStatement(MappedStatement ms) {
- String msId = ms.getId().concat("_COUNT");
- MappedStatement mappedStatement = null;
- try {
- mappedStatement = ms.getConfiguration().getMappedStatement(msId, false);
- } catch (Exception ignored) {
- // do nothing.
- }
- return mappedStatement;
- }
-
- /**
- * 构建 count 查询的 {@link MappedStatement} 对象。
- */
- private MappedStatement buildCountMappedStatement(MappedStatement ms) {
- String countId = ms.getId() + "_Count";
- MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), countId, ms.getSqlSource(), ms.getSqlCommandType());
- return builder.resource(ms.getResource())
- .fetchSize(ms.getFetchSize())
- .statementType(ms.getStatementType())
- .keyGenerator(ms.getKeyGenerator())
- .timeout(ms.getTimeout())
- .parameterMap(ms.getParameterMap())
- .resultMaps(Collections.singletonList(new ResultMap.Builder(ms.getConfiguration(), ms.getId(), Long.class, Collections.emptyList()).build()))
- .resultSetType(ms.getResultSetType())
- .cache(ms.getCache())
- .flushCacheRequired(ms.isFlushCacheRequired())
- .useCache(ms.isUseCache())
- .build();
- }
-
- /**
- * 构建 count 查询 SQL 语句。
- */
- private String getCountSqlStr(String originalSql) {
- return String.format("SELECT COUNT(*) FROM (%s) TOTAL", originalSql);
- }
-
-}
\ No newline at end of file