miemie 5 gadi atpakaļ
vecāks
revīzija
e4a013ded7

+ 11 - 23
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/IPage.java

@@ -33,28 +33,6 @@ import static java.util.stream.Collectors.toList;
  */
 public interface IPage<T> extends Serializable {
 
-    /**
-     * 降序字段数组
-     *
-     * @return order by desc 的字段数组
-     * @see #orders()
-     */
-    @Deprecated
-    default String[] descs() {
-        return null;
-    }
-
-    /**
-     * 升序字段数组
-     *
-     * @return order by asc 的字段数组
-     * @see #orders()
-     */
-    @Deprecated
-    default String[] ascs() {
-        return null;
-    }
-
     /**
      * 获取排序信息,排序的字段和正反序
      *
@@ -177,7 +155,7 @@ public interface IPage<T> extends Serializable {
     IPage<T> setSize(long size);
 
     /**
-     * 当前页,默认 1
+     * 当前页
      *
      * @return 当前页
      */
@@ -201,6 +179,16 @@ public interface IPage<T> extends Serializable {
         return ((IPage<R>) this).setRecords(collect);
     }
 
+    /**
+     * 老分页插件不支持
+     *
+     * @return count的method
+     * @since 3.3.3 @2020-06-19
+     */
+    default String countId() {
+        return null;
+    }
+
     /**
      * 生成缓存key值
      *

+ 0 - 1
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/parser/SqlInfo.java

@@ -62,7 +62,6 @@ public class SqlInfo {
         return info;
     }
 
-    @Deprecated
     public static SqlInfo newInstance() {
         return new SqlInfo().setOrderBy(true);
     }

+ 7 - 2
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/MybatisPlusInterceptor.java

@@ -1,6 +1,5 @@
 package com.baomidou.mybatisplus.extension.plugins;
 
-import com.baomidou.mybatisplus.extension.plugins.chain.PageQiuQiu;
 import com.baomidou.mybatisplus.extension.plugins.chain.QiuQiu;
 import org.apache.ibatis.cache.CacheKey;
 import org.apache.ibatis.executor.Executor;
@@ -13,6 +12,7 @@ import org.apache.ibatis.session.ResultHandler;
 import org.apache.ibatis.session.RowBounds;
 
 import java.sql.Connection;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Properties;
@@ -32,7 +32,7 @@ import java.util.Properties;
 )
 public class MybatisPlusInterceptor implements Interceptor {
 
-    private final List<QiuQiu> qiuQius = Collections.singletonList(new PageQiuQiu());
+    private final List<QiuQiu> qiuQius = new ArrayList<>();
 
     @Override
     public Object intercept(Invocation invocation) throws Throwable {
@@ -90,4 +90,9 @@ public class MybatisPlusInterceptor implements Interceptor {
     public void setProperties(Properties properties) {
         // todo
     }
+
+    public MybatisPlusInterceptor addQiuQiu(QiuQiu qiuQiu) {
+        qiuQius.add(qiuQiu);
+        return this;
+    }
 }

+ 37 - 31
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/chain/PageQiuQiu.java

@@ -5,16 +5,14 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.OrderItem;
 import com.baomidou.mybatisplus.core.parser.ISqlParser;
 import com.baomidou.mybatisplus.core.parser.SqlInfo;
-import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
-import com.baomidou.mybatisplus.core.toolkit.ParameterUtils;
-import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
-import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.*;
 import com.baomidou.mybatisplus.extension.plugins.pagination.DialectFactory;
 import com.baomidou.mybatisplus.extension.plugins.pagination.DialectModel;
 import com.baomidou.mybatisplus.extension.plugins.pagination.dialects.IDialect;
 import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
 import com.baomidou.mybatisplus.extension.toolkit.SqlParserUtils;
 import lombok.Data;
+import lombok.experimental.Accessors;
 import net.sf.jsqlparser.JSQLParserException;
 import net.sf.jsqlparser.parser.CCJSqlParserUtil;
 import net.sf.jsqlparser.schema.Column;
@@ -34,6 +32,7 @@ import org.apache.ibatis.session.RowBounds;
 
 import java.sql.SQLException;
 import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
 
 /**
@@ -41,9 +40,12 @@ import java.util.stream.Collectors;
  * @since 2020-06-16
  */
 @Data
+@Accessors(chain = true)
+@SuppressWarnings({"rawtypes"})
 public class PageQiuQiu implements QiuQiu {
 
     protected static final Log logger = LogFactory.getLog(PageQiuQiu.class);
+    protected static final Map<String, MappedStatement> countMsCache = new ConcurrentHashMap<>();
 
     /**
      * COUNT SQL 解析
@@ -88,13 +90,13 @@ public class PageQiuQiu implements QiuQiu {
             if (page.isSearchCount()) {
                 final String originalSql = boundSql.getSql();
                 SqlInfo sqlInfo = SqlParserUtils.getOptimizeCountSql(page.optimizeCountSql(), countSqlParser, originalSql, SystemMetaObject.forObject(parameter));
-                MappedStatement countMappedStatement = buildCountMappedStatement(ms);
+                MappedStatement countMappedStatement = buildCountMappedStatement(ms, page);
                 PluginUtils.MPBoundSql mpBoundSql = PluginUtils.mpBoundSql(boundSql);
                 BoundSql countSql = new BoundSql(countMappedStatement.getConfiguration(), sqlInfo.getSql(), mpBoundSql.parameterMappings(), parameter);
                 PluginUtils.setAdditionalParameter(countSql, mpBoundSql.additionalParameters());
                 CacheKey cacheKey = executor.createCacheKey(countMappedStatement, parameter, rowBounds, countSql);
-                long count = (long) executor.query(countMappedStatement, parameter, rowBounds, resultHandler, cacheKey, countSql).get(0);
-                page.setTotal(count);
+                Object result = executor.query(countMappedStatement, parameter, rowBounds, resultHandler, cacheKey, countSql).get(0);
+                page.setTotal(Long.parseLong(result.toString()));
                 return continueLimit(page);
             }
         }
@@ -117,7 +119,7 @@ public class PageQiuQiu implements QiuQiu {
             handlerLimit(page);
         }
         String originalSql = boundSql.getSql();
-        DbType dbType = this.dbType == null ? JdbcUtils.getDbType(ms) : this.dbType;
+        DbType dbType = this.dbType == null ? JdbcUtils.getDbType(executor) : this.dbType;
         IDialect dialect = Optional.ofNullable(this.dialect).orElseGet(() -> DialectFactory.getDialect(dbType));
         String buildSql = this.concatOrderBy(originalSql, page);
         DialectModel model = dialect.buildPaginationSql(buildSql, page.offset(), page.getSize());
@@ -130,31 +132,35 @@ public class PageQiuQiu implements QiuQiu {
         mpBoundSql.parameterMappings(mappings);
     }
 
-    protected MappedStatement buildCountMappedStatement(MappedStatement ms) {
-        MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms.getId() + "_mpCount", ms.getSqlSource(), ms.getSqlCommandType());
-        builder.resource(ms.getResource());
-        builder.fetchSize(ms.getFetchSize());
-        builder.statementType(ms.getStatementType());
-        builder.keyGenerator(ms.getKeyGenerator());
-        if (ms.getKeyProperties() != null && ms.getKeyProperties().length != 0) {
-            StringBuilder keyProperties = new StringBuilder();
-            for (String keyProperty : ms.getKeyProperties()) {
-                keyProperties.append(keyProperty).append(",");
+    protected MappedStatement buildCountMappedStatement(MappedStatement ms, IPage<?> page) {
+        String countId = page.countId();
+        final String id = ms.getId();
+        final Configuration configuration = ms.getConfiguration();
+        if (StringUtils.isNotBlank(countId)) {
+            if (!countId.contains(StringPool.DOT)) {
+                countId = id.substring(0, id.lastIndexOf(StringPool.DOT)) + countId;
+            }
+            try {
+                return countMsCache.computeIfAbsent(countId, key -> configuration.getMappedStatement(key, false));
+            } catch (Exception e) {
+                logger.warn(String.format("can not find this countId: [\"%s\"]", countId));
             }
-            keyProperties.delete(keyProperties.length() - 1, keyProperties.length());
-            builder.keyProperty(keyProperties.toString());
         }
-        builder.timeout(ms.getTimeout());
-        builder.parameterMap(ms.getParameterMap());
-        List<ResultMap> resultMaps = new ArrayList<>();
-        ResultMap resultMap = new ResultMap.Builder(ms.getConfiguration(), ms.getId(), Long.class, Collections.emptyList()).build();
-        resultMaps.add(resultMap);
-        builder.resultMaps(resultMaps);
-        builder.resultSetType(ms.getResultSetType());
-        builder.cache(ms.getCache());
-        builder.flushCacheRequired(ms.isFlushCacheRequired());
-        builder.useCache(ms.isUseCache());
-        return builder.build();
+        countId = id + "_mpCount";
+        return countMsCache.computeIfAbsent(countId, key -> {
+            MappedStatement.Builder builder = new MappedStatement.Builder(configuration, key, ms.getSqlSource(), ms.getSqlCommandType());
+            builder.resource(ms.getResource());
+            builder.fetchSize(ms.getFetchSize());
+            builder.statementType(ms.getStatementType());
+            builder.timeout(ms.getTimeout());
+            builder.parameterMap(ms.getParameterMap());
+            builder.resultMaps(Collections.singletonList(new ResultMap.Builder(configuration, "mybatis_plus", Long.class, Collections.emptyList()).build()));
+            builder.resultSetType(ms.getResultSetType());
+            builder.cache(ms.getCache());
+            builder.flushCacheRequired(ms.isFlushCacheRequired());
+            builder.useCache(ms.isUseCache());
+            return builder.build();
+        });
     }
 
     /**

+ 1 - 0
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/chain/QiuQiu.java

@@ -14,6 +14,7 @@ import java.sql.SQLException;
  * @author miemie
  * @since 2020-06-16
  */
+@SuppressWarnings({"rawtypes"})
 public interface QiuQiu {
 
     /**

+ 12 - 28
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/pagination/Page.java

@@ -18,7 +18,9 @@ package com.baomidou.mybatisplus.extension.plugins.pagination;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.OrderItem;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
-import org.jetbrains.annotations.Nullable;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -72,6 +74,13 @@ public class Page<T> implements IPage<T> {
      * 是否命中count缓存
      */
     protected boolean hitCount = false;
+    /**
+     * countId
+     */
+    @Getter
+    @Setter
+    @Accessors(chain = true)
+    protected String countId;
 
     public Page() {
     }
@@ -165,20 +174,9 @@ public class Page<T> implements IPage<T> {
         return this;
     }
 
-    /**
-     * 获取当前正序排列的字段集合
-     * <p>
-     * 为了兼容,将在不久后废弃
-     *
-     * @return 正序排列的字段集合
-     * @see #getOrders()
-     * @deprecated 3.2.0
-     */
     @Override
-    @Nullable
-    @Deprecated
-    public String[] ascs() {
-        return CollectionUtils.isNotEmpty(orders) ? mapOrderToArray(OrderItem::isAsc) : null;
+    public String countId() {
+        return getCountId();
     }
 
     /**
@@ -264,20 +262,6 @@ public class Page<T> implements IPage<T> {
         return this;
     }
 
-    /**
-     * 获取需简要倒序排列的字段数组
-     * <p>
-     *
-     * @return 倒序排列的字段数组
-     * @see #getOrders()
-     * @deprecated 3.2.0
-     */
-    @Override
-    @Deprecated
-    public String[] descs() {
-        return mapOrderToArray(i -> !i.isAsc());
-    }
-
     /**
      * Replaced:{@link #addOrder(OrderItem...)}
      *

+ 10 - 5
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/toolkit/JdbcUtils.java

@@ -19,11 +19,10 @@ import com.baomidou.mybatisplus.annotation.DbType;
 import com.baomidou.mybatisplus.core.toolkit.Assert;
 import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import org.apache.ibatis.executor.Executor;
 import org.apache.ibatis.logging.Log;
 import org.apache.ibatis.logging.LogFactory;
-import org.apache.ibatis.mapping.MappedStatement;
 
-import javax.sql.DataSource;
 import java.sql.Connection;
 import java.sql.SQLException;
 
@@ -37,9 +36,15 @@ public class JdbcUtils {
 
     private static final Log logger = LogFactory.getLog(JdbcUtils.class);
 
-    public static DbType getDbType(MappedStatement ms) {
-        DataSource dataSource = ms.getConfiguration().getEnvironment().getDataSource();
-        try (Connection conn = dataSource.getConnection()) {
+    /**
+     * 不关闭 Connection,因为是从事务里获取的,sqlSession会负责关闭
+     *
+     * @param executor Executor
+     * @return DbType
+     */
+    public static DbType getDbType(Executor executor) {
+        try {
+            Connection conn = executor.getTransaction().getConnection();
             return getDbType(conn.getMetaData().getURL());
         } catch (SQLException e) {
             throw ExceptionUtils.mpe(e);

+ 4 - 2
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/cache/CacheConfig.java

@@ -17,7 +17,8 @@ package com.baomidou.mybatisplus.test.h2.cache;
 
 import com.baomidou.mybatisplus.core.MybatisConfiguration;
 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
-import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.chain.PageQiuQiu;
+import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
 import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
 import org.apache.ibatis.session.ExecutorType;
 import org.apache.ibatis.session.SqlSessionFactory;
@@ -44,7 +45,8 @@ public class CacheConfig {
         configuration.setDefaultEnumTypeHandler(EnumOrdinalTypeHandler.class);
         configuration.setCacheEnabled(true);
         sqlSessionFactory.setConfiguration(configuration);
-        MybatisPlusInterceptor pagination = new MybatisPlusInterceptor();
+        MybatisPlusInterceptor pagination = new MybatisPlusInterceptor().addQiuQiu(new PageQiuQiu()
+            .setCountSqlParser(new JsqlParserCountOptimize(true)));
 
         sqlSessionFactory.setPlugins(pagination);
         return sqlSessionFactory.getObject();

+ 5 - 2
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/config/MybatisPlusConfig.java

@@ -28,8 +28,9 @@ import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn
 import com.baomidou.mybatisplus.extension.injector.methods.LogicDeleteByIdWithFill;
 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
-import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.SqlExplainInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.chain.PageQiuQiu;
+import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
 import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
 import com.baomidou.mybatisplus.test.h2.H2MetaObjectHandler;
 import net.sf.jsqlparser.statement.delete.Delete;
@@ -76,7 +77,9 @@ public class MybatisPlusConfig {
         configuration.setDefaultExecutorType(ExecutorType.REUSE);
         configuration.setDefaultEnumTypeHandler(EnumOrdinalTypeHandler.class);  //默认枚举处理
         sqlSessionFactory.setConfiguration(configuration);
-        MybatisPlusInterceptor pagination = new MybatisPlusInterceptor();
+        MybatisPlusInterceptor pagination = new MybatisPlusInterceptor().addQiuQiu(new PageQiuQiu()
+            .setCountSqlParser(new JsqlParserCountOptimize(true)));
+        ;
         SqlExplainInterceptor sqlExplainInterceptor = new SqlExplainInterceptor();
         List<ISqlParser> sqlParserList = new ArrayList<>();
         sqlParserList.add(new AbstractJsqlParser() {