From 209ec6ab60912047cf5e428619927399c8d10e41 Mon Sep 17 00:00:00 2001 From: Suomm <1474983351@qq.com> Date: Sun, 18 Jun 2023 16:05:04 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E6=9F=A5=E8=AF=A2=E4=BB=A3=E7=A0=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/mybatisflex/core/BaseMapper.java | 73 +++++++++---------- .../com/mybatisflex/core/row/RowMapper.java | 58 ++++++--------- .../com/mybatisflex/core/util/MapperUtil.java | 25 ++++--- 3 files changed, 72 insertions(+), 84 deletions(-) diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java index b7dec258..096edf6a 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java @@ -20,7 +20,10 @@ import com.mybatisflex.core.field.FieldQueryBuilder; import com.mybatisflex.core.mybatis.MappedStatementTypes; import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.provider.EntitySqlProvider; -import com.mybatisflex.core.query.*; +import com.mybatisflex.core.query.CPI; +import com.mybatisflex.core.query.QueryColumn; +import com.mybatisflex.core.query.QueryCondition; +import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.table.TableInfo; import com.mybatisflex.core.table.TableInfoFactory; import com.mybatisflex.core.util.*; @@ -667,47 +670,39 @@ public interface BaseMapper { default Page paginateAs(Page page, QueryWrapper queryWrapper, Class asType, Consumer>... consumers) { - List selectColumns = CPI.getSelectColumns(queryWrapper); - List orderBys = CPI.getOrderBys(queryWrapper); - List joins = CPI.getJoins(queryWrapper); - // 只有 totalRow 小于 0 的时候才会去查询总量 - // 这样方便用户做总数缓存,而非每次都要去查询总量 - // 一般的分页场景中,只有第一页的时候有必要去查询总量,第二页以后是不需要的 - if (page.getTotalRow() < 0) { - QueryWrapper countQueryWrapper = MapperUtil.optimizeCountQueryWrapper(queryWrapper); - long count = selectCountByQuery(countQueryWrapper); - page.setTotalRow(count); - } + try { + // 只有 totalRow 小于 0 的时候才会去查询总量 + // 这样方便用户做总数缓存,而非每次都要去查询总量 + // 一般的分页场景中,只有第一页的时候有必要去查询总量,第二页以后是不需要的 + if (page.getTotalRow() < 0) { + QueryWrapper countQueryWrapper = MapperUtil.optimizeCountQueryWrapper(queryWrapper); + page.setTotalRow(selectCountByQuery(countQueryWrapper)); + } + + if (page.isEmpty()) { + return page; + } + + int offset = page.getPageSize() * (page.getPageNumber() - 1); + queryWrapper.limit(offset, page.getPageSize()); + + List records; + if (asType != null) { + records = selectListByQueryAs(queryWrapper, asType); + } else { + records = (List) selectListByQuery(queryWrapper); + } + MapperUtil.queryFields(this, records, consumers); + page.setRecords(records); - if (page.isEmpty()) { return page; + + } finally { + // 将之前设置的 limit 清除掉 + // 保险起见把重置代码放到 finally 代码块中 + CPI.setLimitRows(queryWrapper, null); + CPI.setLimitOffset(queryWrapper, null); } - - //重置 selectColumns - CPI.setSelectColumns(queryWrapper, selectColumns); - //重置 orderBys - CPI.setOrderBys(queryWrapper, orderBys); - //重置 join - CPI.setJoins(queryWrapper, joins); - - int offset = page.getPageSize() * (page.getPageNumber() - 1); - queryWrapper.limit(offset, page.getPageSize()); - - if (asType != null) { - List records = selectListByQueryAs(queryWrapper, asType); - MapperUtil.queryFields(this, records, consumers); - page.setRecords(records); - } else { - List records = (List) selectListByQuery(queryWrapper); - MapperUtil.queryFields(this, records, consumers); - page.setRecords(records); - } - - // 将之前设置的 limit 清除掉 - CPI.setLimitRows(queryWrapper, null); - CPI.setLimitOffset(queryWrapper, null); - - return page; } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/RowMapper.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/RowMapper.java index 1c79619f..ea418f20 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/RowMapper.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/RowMapper.java @@ -19,7 +19,9 @@ import com.mybatisflex.core.FlexConsts; import com.mybatisflex.core.exception.FlexExceptions; import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.provider.RowSqlProvider; -import com.mybatisflex.core.query.*; +import com.mybatisflex.core.query.CPI; +import com.mybatisflex.core.query.QueryColumn; +import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.util.CollectionUtil; import com.mybatisflex.core.util.MapperUtil; import com.mybatisflex.core.util.StringUtil; @@ -431,47 +433,35 @@ public interface RowMapper { * @return */ default Page paginate(String schema, String tableName, Page page, QueryWrapper queryWrapper) { + try { + CPI.setFromIfNecessary(queryWrapper, schema, tableName); - CPI.setFromIfNecessary(queryWrapper, schema, tableName); + // 只有 totalRow 小于 0 的时候才会去查询总量 + // 这样方便用户做总数缓存,而非每次都要去查询总量 + // 一般的分页场景中,只有第一页的时候有必要去查询总量,第二页以后是不需要的 + if (page.getTotalRow() < 0) { + QueryWrapper countQueryWrapper = MapperUtil.optimizeCountQueryWrapper(queryWrapper); + page.setTotalRow(selectCountByQuery(schema, tableName, countQueryWrapper)); + } - List selectColumns = CPI.getSelectColumns(queryWrapper); + if (page.isEmpty()) { + return page; + } - List orderBys = CPI.getOrderBys(queryWrapper); + int offset = page.getPageSize() * (page.getPageNumber() - 1); + queryWrapper.limit(offset, page.getPageSize()); - List joins = CPI.getJoins(queryWrapper); + page.setRecords(selectListByQuery(schema, tableName, queryWrapper)); - // 只有 totalRow 小于 0 的时候才会去查询总量 - // 这样方便用户做总数缓存,而非每次都要去查询总量 - // 一般的分页场景中,只有第一页的时候有必要去查询总量,第二页以后是不需要的 - if (page.getTotalRow() < 0) { - QueryWrapper countQueryWrapper = MapperUtil.optimizeCountQueryWrapper(queryWrapper); - long count = selectCountByQuery(schema, tableName, countQueryWrapper); - page.setTotalRow(count); - } - - if (page.isEmpty()) { return page; + + } finally { + // 将之前设置的 limit 清除掉 + // 保险起见把重置代码放到 finally 代码块中 + CPI.setLimitRows(queryWrapper, null); + CPI.setLimitOffset(queryWrapper, null); } - //重置 selectColumns - CPI.setSelectColumns(queryWrapper, selectColumns); - //重置 orderBys - CPI.setOrderBys(queryWrapper, orderBys); - //重置 join - CPI.setJoins(queryWrapper, joins); - - int offset = page.getPageSize() * (page.getPageNumber() - 1); - queryWrapper.limit(offset, page.getPageSize()); - - List records = selectListByQuery(schema, tableName, queryWrapper); - page.setRecords(records); - - // 将之前设置的 limit 清除掉 - CPI.setLimitRows(queryWrapper, null); - CPI.setLimitOffset(queryWrapper, null); - - return page; - } } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/MapperUtil.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/MapperUtil.java index d8e2c1ea..3f8f40b8 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/MapperUtil.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/MapperUtil.java @@ -42,7 +42,7 @@ public class MapperUtil { * *

      * {@code
-     * SELECT COUNT(*) AS `total` FROM ( ...用户构建的 SQL 语句... );
+     * SELECT COUNT(*) AS `total` FROM ( ...用户构建的 SQL 语句... ) AS `t`;
      * }
      * 
* @@ -58,22 +58,25 @@ public class MapperUtil { * 优化 COUNT 查询语句。 */ public static QueryWrapper optimizeCountQueryWrapper(QueryWrapper queryWrapper) { - List selectColumns = CPI.getSelectColumns(queryWrapper); - List groupByColumns = CPI.getGroupByColumns(queryWrapper); + // 对克隆对象进行操作,不影响原来的 QueryWrapper 对象 + QueryWrapper clone = queryWrapper.clone(); + // 将最后面的 order by 移除掉 + CPI.setOrderBys(clone, null); + // 获取查询列和分组列,用于判断是否进行优化 + List selectColumns = CPI.getSelectColumns(clone); + List groupByColumns = CPI.getGroupByColumns(clone); // 如果有 distinct 语句或者 group by 语句则不优化 // 这种一旦优化了就会造成 count 语句查询出来的值不对 if (hasDistinct(selectColumns) || hasGroupBy(groupByColumns)) { - return rawCountQueryWrapper(queryWrapper); + return rawCountQueryWrapper(clone); } // 判断能不能清除 join 语句 - if (canClearJoins(queryWrapper)) { - CPI.setJoins(queryWrapper, null); + if (canClearJoins(clone)) { + CPI.setJoins(clone, null); } - // 最后将最后面的 order by 移除掉 - // 将 select 里面的列换成 COUNT(*) AS `total` 就好了 - CPI.setOrderBys(queryWrapper, null); - CPI.setSelectColumns(queryWrapper, Collections.singletonList(count().as("total"))); - return queryWrapper; + // 将 select 里面的列换成 COUNT(*) AS `total` + CPI.setSelectColumns(clone, Collections.singletonList(count().as("total"))); + return clone; } private static boolean hasDistinct(List selectColumns) {