Forráskód Böngészése

优化 page 分页可自动填充 records

= 7 éve
szülő
commit
8bb7e11aaf

+ 0 - 9
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/mapper/LogicAllSqlInjector.java

@@ -15,14 +15,7 @@
  */
 package com.baomidou.mybatisplus.mapper;
 
-import com.baomidou.mybatisplus.entity.TableFieldInfo;
 import com.baomidou.mybatisplus.entity.TableInfo;
-import com.baomidou.mybatisplus.enums.SqlMethod;
-import com.baomidou.mybatisplus.toolkit.StringUtils;
-import org.apache.ibatis.mapping.SqlSource;
-
-import java.util.List;
-import java.util.Map;
 
 /**
  * <p>
@@ -58,6 +51,4 @@ public class LogicAllSqlInjector extends SuperLogicSqlInjector {
     protected void injectDeleteByMapSql(Class<?> mapperClass, TableInfo table) {
         super.injectDeleteByMapSql(mapperClass, table);
     }
-
-
 }

+ 0 - 1
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/mapper/LogicSqlInjector.java

@@ -16,7 +16,6 @@
 package com.baomidou.mybatisplus.mapper;
 
 import java.util.List;
-import java.util.Map;
 
 import org.apache.ibatis.mapping.SqlSource;
 import org.apache.ibatis.scripting.defaults.RawSqlSource;

+ 5 - 7
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/mapper/SuperLogicSqlInjector.java

@@ -1,13 +1,14 @@
 package com.baomidou.mybatisplus.mapper;
 
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ibatis.mapping.SqlSource;
+
 import com.baomidou.mybatisplus.entity.TableFieldInfo;
 import com.baomidou.mybatisplus.entity.TableInfo;
 import com.baomidou.mybatisplus.enums.SqlMethod;
 import com.baomidou.mybatisplus.toolkit.StringUtils;
-import org.apache.ibatis.mapping.SqlSource;
-
-import java.util.List;
-import java.util.Map;
 
 /**
  * <p>
@@ -111,7 +112,4 @@ public class SuperLogicSqlInjector extends AutoSqlInjector {
         }
         return set.toString();
     }
-
-
-
 }

+ 0 - 127
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/plugins/CachePaginationInterceptor.java

@@ -1,127 +0,0 @@
-/**
- * Copyright (c) 2011-2020, hubin (jobob@qq.com).
- * <p>
- * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.baomidou.mybatisplus.plugins;
-
-import java.sql.Connection;
-import java.util.Properties;
-
-import org.apache.ibatis.executor.Executor;
-import org.apache.ibatis.executor.statement.StatementHandler;
-import org.apache.ibatis.mapping.BoundSql;
-import org.apache.ibatis.mapping.MappedStatement;
-import org.apache.ibatis.plugin.Interceptor;
-import org.apache.ibatis.plugin.Intercepts;
-import org.apache.ibatis.plugin.Invocation;
-import org.apache.ibatis.plugin.Plugin;
-import org.apache.ibatis.plugin.Signature;
-import org.apache.ibatis.session.ResultHandler;
-import org.apache.ibatis.session.RowBounds;
-
-import com.baomidou.mybatisplus.plugins.pagination.Pagination;
-import com.baomidou.mybatisplus.plugins.parser.ISqlParser;
-import com.baomidou.mybatisplus.plugins.parser.SqlInfo;
-import com.baomidou.mybatisplus.toolkit.SqlUtils;
-
-/**
- * <p>
- * 缓存分页拦截器
- * </p>
- *
- * @author hubin
- * @Date 2016-01-23
- */
-@Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
-        @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
-public class CachePaginationInterceptor extends PaginationInterceptor implements Interceptor {
-
-    /**
-     * COUNT SQL 解析
-     */
-    private ISqlParser sqlParser;
-    /**
-     * 溢出总页数,设置第一页
-     */
-    private boolean overflowCurrent = false;
-
-    /**
-     * Physical Pagination Interceptor for all the queries with parameter
-     * {@link org.apache.ibatis.session.RowBounds}
-     */
-    @Override
-    public Object intercept(Invocation invocation) throws Throwable {
-
-        Object target = invocation.getTarget();
-        if (target instanceof StatementHandler) {
-            return super.intercept(invocation);
-        } else {
-            RowBounds rowBounds = (RowBounds) invocation.getArgs()[2];
-            if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {
-                return invocation.proceed();
-            }
-            MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
-            Executor executor = (Executor) invocation.getTarget();
-            Connection connection = executor.getTransaction().getConnection();
-            Object parameterObject = invocation.getArgs()[1];
-            BoundSql boundSql = mappedStatement.getBoundSql(parameterObject);
-            String originalSql = boundSql.getSql();
-            if (rowBounds instanceof Pagination) {
-                Pagination page = (Pagination) rowBounds;
-                if (page.isSearchCount()) {
-                    SqlInfo sqlInfo = SqlUtils.getOptimizeCountSql(page.isOptimizeCountSql(), sqlParser, originalSql);
-                    super.queryTotal(overflowCurrent, sqlInfo.getSql(), mappedStatement, boundSql, page, connection);
-                    if (page.getTotal() <= 0) {
-                        return invocation.proceed();
-                    }
-                }
-            }
-        }
-        return invocation.proceed();
-    }
-
-    @Override
-    public Object plugin(Object target) {
-        if (target instanceof Executor) {
-            return Plugin.wrap(target, this);
-        }
-        if (target instanceof StatementHandler) {
-            return Plugin.wrap(target, this);
-        }
-        return target;
-    }
-
-    @Override
-    public void setProperties(Properties prop) {
-
-    }
-
-    @Override
-    public CachePaginationInterceptor setDialectType(String dialectType) {
-        return this;
-    }
-
-    @Override
-    public CachePaginationInterceptor setSqlParser(ISqlParser sqlParser) {
-        this.sqlParser = sqlParser;
-        return this;
-    }
-
-    @Override
-    public CachePaginationInterceptor setOverflowCurrent(boolean overflowCurrent) {
-        this.overflowCurrent = overflowCurrent;
-        return this;
-    }
-
-}

+ 96 - 82
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/plugins/PaginationInterceptor.java

@@ -16,10 +16,11 @@
 package com.baomidou.mybatisplus.plugins;
 
 import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
+import java.util.List;
 import java.util.Properties;
 
+import org.apache.ibatis.cache.CacheKey;
+import org.apache.ibatis.executor.Executor;
 import org.apache.ibatis.executor.statement.StatementHandler;
 import org.apache.ibatis.logging.Log;
 import org.apache.ibatis.logging.LogFactory;
@@ -33,10 +34,10 @@ import org.apache.ibatis.plugin.Plugin;
 import org.apache.ibatis.plugin.Signature;
 import org.apache.ibatis.reflection.MetaObject;
 import org.apache.ibatis.reflection.SystemMetaObject;
-import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;
+import org.apache.ibatis.session.Configuration;
+import org.apache.ibatis.session.ResultHandler;
 import org.apache.ibatis.session.RowBounds;
 
-import com.baomidou.mybatisplus.MybatisDefaultParameterHandler;
 import com.baomidou.mybatisplus.enums.DBType;
 import com.baomidou.mybatisplus.plugins.pagination.DialectFactory;
 import com.baomidou.mybatisplus.plugins.pagination.PageHelper;
@@ -56,7 +57,11 @@ import com.baomidou.mybatisplus.toolkit.StringUtils;
  * @author hubin
  * @Date 2016-01-23
  */
-@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
+@Intercepts({
+    @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}),
+    @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})
+})
 public class PaginationInterceptor extends SqlParserHandler implements Interceptor {
 
     /**
@@ -85,101 +90,110 @@ public class PaginationInterceptor extends SqlParserHandler implements Intercept
     private boolean localPage = false;
 
     /**
-     * Physical Pagination Interceptor for all the queries with parameter {@link org.apache.ibatis.session.RowBounds}
+     * Physical Pagination Interceptor for all the queries with parameter {@link RowBounds}
      */
     @Override
     public Object intercept(Invocation invocation) throws Throwable {
-        StatementHandler statementHandler = (StatementHandler) PluginUtils.realTarget(invocation.getTarget());
-        MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
-        this.sqlParser(metaObject);
-        // 先判断是不是SELECT操作
-        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
-        if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) {
+        Object target = invocation.getTarget();
+        if (target instanceof StatementHandler) {
+            /**
+             * SQL 解析链处理
+             */
+            StatementHandler statementHandler = (StatementHandler) PluginUtils.realTarget(invocation.getTarget());
+            MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
+            this.sqlParser(metaObject);
             return invocation.proceed();
-        }
-        RowBounds rowBounds = (RowBounds) metaObject.getValue("delegate.rowBounds");
-        /* 不需要分页的场合 */
-        if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {
-            // 本地线程分页
-            if (localPage) {
-                // 采用ThreadLocal变量处理的分页
-                rowBounds = PageHelper.getPagination();
-                if (rowBounds == null) {
-                    return invocation.proceed();
-                }
-            } else {
-                // 无需分页
+        } else if (target instanceof Executor) {
+            /**
+             * PAGE 分页逻辑处理
+             */
+            // 先判断是不是SELECT操作
+            Object[] args = invocation.getArgs();
+            MappedStatement mappedStatement = (MappedStatement) args[0];
+            if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) {
                 return invocation.proceed();
             }
-        }
-        // 针对定义了rowBounds,做为mapper接口方法的参数
-        BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
-        String originalSql = boundSql.getSql();
-        Connection connection = (Connection) invocation.getArgs()[0];
-        DBType dbType = StringUtils.isNotEmpty(dialectType) ? DBType.getDBType(dialectType) : JdbcUtils.getDbType(connection.getMetaData().getURL());
-        if (rowBounds instanceof Pagination) {
-            Pagination page = (Pagination) rowBounds;
-            boolean orderBy = true;
-            if (page.isSearchCount()) {
-                SqlInfo sqlInfo = SqlUtils.getOptimizeCountSql(page.isOptimizeCountSql(), sqlParser, originalSql);
-                orderBy = sqlInfo.isOrderBy();
-                this.queryTotal(overflowCurrent, sqlInfo.getSql(), mappedStatement, boundSql, page, connection);
-                if (page.getTotal() <= 0) {
+            RowBounds rowBounds = (RowBounds) args[2];
+            /* 不需要分页的场合 */
+            if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {
+                // 本地线程分页
+                if (localPage) {
+                    // 采用ThreadLocal变量处理的分页
+                    rowBounds = PageHelper.getPagination();
+                    if (rowBounds == null) {
+                        return invocation.proceed();
+                    }
+                } else {
+                    // 无需分页
                     return invocation.proceed();
                 }
             }
-            String buildSql = SqlUtils.concatOrderBy(originalSql, page, orderBy);
-            originalSql = DialectFactory.buildPaginationSql(page, buildSql, dbType, dialectClazz);
-        } else {
-            // support physical Pagination for RowBounds
-            originalSql = DialectFactory.buildPaginationSql(rowBounds, originalSql, dbType, dialectClazz);
-        }
-
-        /*
-         * <p> 禁用内存分页 </p>
-         * <p> 内存分页会查询所有结果出来处理(这个很吓人的),如果结果变化频繁这个数据还会不准。</p>
-         */
-        metaObject.setValue("delegate.boundSql.sql", originalSql);
-        metaObject.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);
-        metaObject.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);
-        return invocation.proceed();
-    }
+            Object parameter = args[1];
+            ResultHandler resultHandler = (ResultHandler) args[3];
+            Executor executor = (Executor) invocation.getTarget();
+            CacheKey cacheKey;
+            BoundSql boundSql;
+            if (args.length == 4) {
+                // 4 个参数时
+                boundSql = mappedStatement.getBoundSql(parameter);
+                cacheKey = executor.createCacheKey(mappedStatement, parameter, rowBounds, boundSql);
+            } else {
+                // 6 个参数时
+                cacheKey = (CacheKey) args[4];
+                boundSql = (BoundSql) args[5];
+            }
 
-    /**
-     * 查询总记录条数
-     *
-     * @param sql
-     * @param mappedStatement
-     * @param boundSql
-     * @param page
-     */
-    protected void queryTotal(boolean overflowCurrent, String sql, MappedStatement mappedStatement, BoundSql boundSql, Pagination page, Connection connection) {
-        try (PreparedStatement statement = connection.prepareStatement(sql)) {
-            DefaultParameterHandler parameterHandler = new MybatisDefaultParameterHandler(mappedStatement, boundSql.getParameterObject(), boundSql);
-            parameterHandler.setParameters(statement);
-            int total = 0;
-            try (ResultSet resultSet = statement.executeQuery()) {
-                if (resultSet.next()) {
-                    total = resultSet.getInt(1);
+            // 针对定义了rowBounds,做为mapper接口方法的参数
+            String originalSql = boundSql.getSql();
+            Connection connection = executor.getTransaction().getConnection();
+            DBType dbType = StringUtils.isNotEmpty(dialectType) ? DBType.getDBType(dialectType) : JdbcUtils.getDbType(connection.getMetaData().getURL());
+            Configuration configuration = mappedStatement.getConfiguration();
+            if (rowBounds instanceof Pagination) {
+                Pagination page = (Pagination) rowBounds;
+                boolean orderBy = true;
+                if (page.isSearchCount()) {
+                    SqlInfo sqlInfo = SqlUtils.getOptimizeCountSql(page.isOptimizeCountSql(), sqlParser, originalSql);
+                    orderBy = sqlInfo.isOrderBy();
+                    BoundSql countBoundSql = new BoundSql(configuration, sqlInfo.getSql(), boundSql.getParameterMappings(), parameter);
+                    CacheKey countCacheKey = executor.createCacheKey(mappedStatement, parameter, RowBounds.DEFAULT, countBoundSql);
+                    // 查询总记录数
+                    Object countObject = executor.query(mappedStatement, parameter, RowBounds.DEFAULT, resultHandler, countCacheKey, countBoundSql);
+//                Map tempMap = (Map) countList.get(0);
+//                Object[] tempArray = tempMap.entrySet().toArray();
+//                Map.Entry totalCount = (Map.Entry) tempArray[0];
+//                page.setTotal((Long) totalCount.getValue());
+                    page.setTotal(6);
+                    // 溢出总页数,设置第一页
+                    long pages = page.getPages();
+                    if (overflowCurrent && (page.getCurrent() > pages)) {
+                        // 设置为第一条
+                        page.setCurrent(1);
+                    }
+                    if (page.getTotal() <= 0L) {
+                        return invocation.proceed();
+                    }
                 }
+                String buildSql = SqlUtils.concatOrderBy(originalSql, page, orderBy);
+                originalSql = DialectFactory.buildPaginationSql(page, buildSql, dbType, dialectClazz);
+            } else {
+                // support physical Pagination for RowBounds
+                originalSql = DialectFactory.buildPaginationSql(rowBounds, originalSql, dbType, dialectClazz);
             }
-            page.setTotal(total);
-            /*
-             * 溢出总页数,设置第一页
-             */
-            int pages = page.getPages();
-            if (overflowCurrent && (page.getCurrent() > pages)) {
-                // 设置为第一条
-                page.setCurrent(1);
+            // 查询记录数
+            BoundSql pageBoundSql = new BoundSql(configuration, originalSql, boundSql.getParameterMappings(), parameter);
+            List records = executor.query(mappedStatement, parameter, RowBounds.DEFAULT, resultHandler, cacheKey, pageBoundSql);
+            if (rowBounds instanceof Page) {
+                Page page = (Page) rowBounds;
+                page.setRecords(records);
             }
-        } catch (Exception e) {
-            logger.error("Error: Method queryTotal execution error !", e);
+            return records;
         }
+        return invocation.proceed();
     }
 
     @Override
     public Object plugin(Object target) {
-        if (target instanceof StatementHandler) {
+        if (target instanceof StatementHandler || target instanceof Executor) {
             return Plugin.wrap(target, this);
         }
         return target;

+ 6 - 5
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/plugins/parser/logicdelete/LogicDeleteDefaultHandler.java

@@ -15,17 +15,18 @@
  */
 package com.baomidou.mybatisplus.plugins.parser.logicdelete;
 
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
 import com.baomidou.mybatisplus.entity.TableFieldInfo;
 import com.baomidou.mybatisplus.entity.TableInfo;
 import com.baomidou.mybatisplus.toolkit.TableInfoHelper;
+
 import net.sf.jsqlparser.expression.Expression;
 import net.sf.jsqlparser.expression.LongValue;
 import net.sf.jsqlparser.expression.StringValue;
 
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
 /**
  * <p>
  * 逻辑删除处理器
@@ -47,7 +48,7 @@ public class LogicDeleteDefaultHandler implements LogicDeleteHandler {
             List<TableInfo> tableInfos = TableInfoHelper.getTableInfos();
             for (TableInfo tableInfo : tableInfos) {
                 List<TableFieldInfo> tableFieldInfos = tableInfo.getFieldList();
-                for (TableFieldInfo tableFieldInfo: tableFieldInfos) {
+                for (TableFieldInfo tableFieldInfo : tableFieldInfos) {
                     if (tableFieldInfo.isLogicDelete()) {
                         tableLogicDeleteMap.put(tableInfo.getTableName(), tableFieldInfo);
                         break;

+ 14 - 3
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/plugins/parser/logicdelete/LogicDeleteSqlParser.java

@@ -15,8 +15,11 @@
  */
 package com.baomidou.mybatisplus.plugins.parser.logicdelete;
 
+import java.util.List;
+
 import com.baomidou.mybatisplus.exceptions.MybatisPlusException;
 import com.baomidou.mybatisplus.plugins.parser.AbstractJsqlParser;
+
 import net.sf.jsqlparser.expression.BinaryExpression;
 import net.sf.jsqlparser.expression.Expression;
 import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
@@ -25,11 +28,19 @@ import net.sf.jsqlparser.schema.Column;
 import net.sf.jsqlparser.schema.Table;
 import net.sf.jsqlparser.statement.delete.Delete;
 import net.sf.jsqlparser.statement.insert.Insert;
-import net.sf.jsqlparser.statement.select.*;
+import net.sf.jsqlparser.statement.select.FromItem;
+import net.sf.jsqlparser.statement.select.Join;
+import net.sf.jsqlparser.statement.select.LateralSubSelect;
+import net.sf.jsqlparser.statement.select.PlainSelect;
+import net.sf.jsqlparser.statement.select.SelectBody;
+import net.sf.jsqlparser.statement.select.SelectExpressionItem;
+import net.sf.jsqlparser.statement.select.SetOperationList;
+import net.sf.jsqlparser.statement.select.SubJoin;
+import net.sf.jsqlparser.statement.select.SubSelect;
+import net.sf.jsqlparser.statement.select.ValuesList;
+import net.sf.jsqlparser.statement.select.WithItem;
 import net.sf.jsqlparser.statement.update.Update;
 
-import java.util.List;
-
 /**
  * <p>
  * 逻辑删除 SQL 解析

+ 1 - 1
mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/test/h2/H2UserTest.java

@@ -232,7 +232,7 @@ public class H2UserTest extends AbstractH2UserTest {
         param.put("ageTo", 100);
         Page<H2User> page = new Page<H2User>(0, 10);
         userMapper.selectUserWithDollarParamInSelectStatememt4Page(param, page);
-        Assert.assertNotEquals(0, page.getTotal());
+        Assert.assertNotEquals(0L, page.getTotal());
 
     }
 

+ 1 - 1
mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/test/h2/base/AbstractH2UserTest.java

@@ -89,7 +89,7 @@ public abstract class AbstractH2UserTest extends H2Test{
         int size = 3;
         Page<H2User> page = userService.selectPage(new Page<H2User>(1, size));
         Assert.assertEquals(size, page.getRecords().size());
-        int total = page.getTotal();
+        long total = page.getTotal();
         page = userService.selectPage(new Page<H2User>(2, size));
         if (total >= size * 2) {
             Assert.assertEquals(size, page.getRecords().size());

+ 3 - 3
mybatis-plus-support/src/main/java/com/baomidou/mybatisplus/plugins/pagination/PageHelper.java

@@ -38,7 +38,7 @@ public class PageHelper {
      * 获取总条数
      * </p>
      */
-    public static int getTotal() {
+    public static long getTotal() {
         if (isPageable()) {
             return LOCAL_PAGE.get().getTotal();
         } else {
@@ -79,8 +79,8 @@ public class PageHelper {
      * 释放资源并获取总条数
      * </p>
      */
-    public static int freeTotal() {
-        int total = getTotal();
+    public static long freeTotal() {
+        long total = getTotal();
         // 释放资源
         remove();
         return total;

+ 6 - 6
mybatis-plus-support/src/main/java/com/baomidou/mybatisplus/plugins/pagination/Pagination.java

@@ -41,7 +41,7 @@ public class Pagination extends RowBounds implements Serializable {
     /**
      * 总数
      */
-    private int total;
+    private long total;
 
     /**
      * 每页显示条数,默认 10
@@ -51,7 +51,7 @@ public class Pagination extends RowBounds implements Serializable {
     /**
      * 总页数
      */
-    private int pages;
+    private long pages;
 
     /**
      * 当前页
@@ -148,11 +148,11 @@ public class Pagination extends RowBounds implements Serializable {
         return this.current < this.pages;
     }
 
-    public int getTotal() {
+    public long getTotal() {
         return total;
     }
 
-    public Pagination setTotal(int total) {
+    public Pagination setTotal(long total) {
         this.total = total;
         return this;
     }
@@ -166,9 +166,9 @@ public class Pagination extends RowBounds implements Serializable {
         return this;
     }
 
-    public int getPages() {
+    public long getPages() {
         if (this.size == 0) {
-            return 0;
+            return 0L;
         }
         this.pages = this.total / this.size;
         if (this.total % this.size != 0) {