001/*
002 *  Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
003 *  <p>
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *  <p>
008 *  http://www.apache.org/licenses/LICENSE-2.0
009 *  <p>
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package com.mybatisflex.core;
017
018import com.mybatisflex.core.exception.FlexExceptions;
019import com.mybatisflex.core.field.FieldQueryBuilder;
020import com.mybatisflex.core.mybatis.MappedStatementTypes;
021import com.mybatisflex.core.paginate.Page;
022import com.mybatisflex.core.provider.EntitySqlProvider;
023import com.mybatisflex.core.query.*;
024import com.mybatisflex.core.table.TableInfo;
025import com.mybatisflex.core.table.TableInfoFactory;
026import com.mybatisflex.core.util.*;
027import org.apache.ibatis.annotations.*;
028import org.apache.ibatis.builder.annotation.ProviderContext;
029import org.apache.ibatis.cursor.Cursor;
030
031import java.io.Serializable;
032import java.util.*;
033import java.util.function.Consumer;
034
035import static com.mybatisflex.core.query.QueryMethods.count;
036
037public interface BaseMapper<T> {
038
039    /**
040     * 插入 entity 数据
041     *
042     * @param entity 实体类
043     * @return 返回影响的行数
044     */
045    default int insert(T entity) {
046        return insert(entity, false);
047    }
048
049
050    /**
051     * 插入 entity 数据,但是忽略 null 的数据,只对有值的内容进行插入
052     * 这样的好处是数据库已经配置了一些默认值,这些默认值才会生效
053     *
054     * @param entity 实体类
055     * @return 返回影响的行数
056     */
057    default int insertSelective(T entity) {
058        return insert(entity, true);
059    }
060
061
062    /**
063     * 插入 entity 数据
064     *
065     * @param entity 实体类
066     * @return 返回影响的行数
067     * @see com.mybatisflex.core.provider.EntitySqlProvider#insert(Map, ProviderContext)
068     */
069    @InsertProvider(type = EntitySqlProvider.class, method = "insert")
070    int insert(@Param(FlexConsts.ENTITY) T entity, @Param(FlexConsts.IGNORE_NULLS) boolean ignoreNulls);
071
072
073    /**
074     * 批量插入 entity 数据,只会根据第一条数据来构建插入的字段内容
075     *
076     * @param entities 插入的数据列表
077     * @return 返回影响的行数
078     * @see com.mybatisflex.core.provider.EntitySqlProvider#insertBatch(Map, ProviderContext)
079     * @see com.mybatisflex.core.FlexConsts#METHOD_INSERT_BATCH
080     */
081    @InsertProvider(type = EntitySqlProvider.class, method = FlexConsts.METHOD_INSERT_BATCH)
082    int insertBatch(@Param(FlexConsts.ENTITIES) List<T> entities);
083
084    /**
085     * 批量插入 entity 数据,按 size 切分
086     *
087     * @param entities 插入的数据列表
088     * @param size     切分大小
089     * @return 影响行数
090     */
091    default int insertBatch(List<T> entities, int size) {
092        if (size <= 0) {
093            size = 1000;//默认1000
094        }
095        int sum = 0;
096        int entitiesSize = entities.size();
097        int maxIndex = entitiesSize / size + (entitiesSize % size == 0 ? 0 : 1);
098        for (int i = 0; i < maxIndex; i++) {
099            List<T> list = entities.subList(i * size, Math.min(i * size + size, entitiesSize));
100            sum += insertBatch(list);
101        }
102        return sum;
103    }
104
105    /**
106     * 新增 或者 更新,若主键有值,则更新,若没有主键值,则插入
107     *
108     * @param entity 实体类
109     * @return 返回影响的行数
110     */
111    default int insertOrUpdate(T entity) {
112        TableInfo tableInfo = TableInfoFactory.ofEntityClass(entity.getClass());
113        Object[] pkArgs = tableInfo.buildPkSqlArgs(entity);
114        if (pkArgs.length == 0 || pkArgs[0] == null) {
115            return insert(entity);
116        } else {
117            return update(entity);
118        }
119    }
120
121    /**
122     * 根据 id 删除数据
123     * 如果是多个主键的情况下,需要传入数组 new Object[]{100,101}
124     *
125     * @param id 主键数据
126     * @return 返回影响的行数
127     * @see com.mybatisflex.core.provider.EntitySqlProvider#deleteById(Map, ProviderContext)
128     */
129    @DeleteProvider(type = EntitySqlProvider.class, method = "deleteById")
130    int deleteById(@Param(FlexConsts.PRIMARY_VALUE) Serializable id);
131
132
133    /**
134     * 根据多个 id 批量删除数据
135     *
136     * @param ids ids 列表
137     * @return 返回影响的行数
138     * @see com.mybatisflex.core.provider.EntitySqlProvider#deleteBatchByIds(Map, ProviderContext)
139     */
140    @DeleteProvider(type = EntitySqlProvider.class, method = "deleteBatchByIds")
141    int deleteBatchByIds(@Param(FlexConsts.PRIMARY_VALUE) Collection<? extends Serializable> ids);
142
143    /**
144     * 根据多个 id 批量删除数据
145     *
146     * @param ids  ids 列表
147     * @param size 切分大小
148     * @return 返回影响的行数
149     * @see com.mybatisflex.core.provider.EntitySqlProvider#deleteBatchByIds(Map, ProviderContext)
150     */
151    default int deleteBatchByIds(List<? extends Serializable> ids, int size) {
152        if (size <= 0) {
153            size = 1000;//默认1000
154        }
155        int sum = 0;
156        int entitiesSize = ids.size();
157        int maxIndex = entitiesSize / size + (entitiesSize % size == 0 ? 0 : 1);
158        for (int i = 0; i < maxIndex; i++) {
159            List<? extends Serializable> list = ids.subList(i * size, Math.min(i * size + size, entitiesSize));
160            sum += deleteBatchByIds(list);
161        }
162        return sum;
163    }
164
165
166    /**
167     * 根据 map 构建的条件来删除数据
168     *
169     * @param whereConditions 条件
170     * @return 返回影响的行数
171     */
172    default int deleteByMap(Map<String, Object> whereConditions) {
173        if (ObjectUtil.areNull(whereConditions) || whereConditions.isEmpty()) {
174            throw FlexExceptions.wrap("deleteByMap is not allow empty map.");
175        }
176        return deleteByQuery(QueryWrapper.create().where(whereConditions));
177    }
178
179    /**
180     * 根据条件来删除数据
181     *
182     * @param condition 条件
183     * @return 返回影响的行数
184     */
185    default int deleteByCondition(QueryCondition condition) {
186        return deleteByQuery(QueryWrapper.create().where(condition));
187    }
188
189    /**
190     * 根据 query 构建的条件来数据吗
191     *
192     * @param queryWrapper query 条件
193     * @return 返回影响的行数
194     * @see com.mybatisflex.core.provider.EntitySqlProvider#deleteByQuery(Map, ProviderContext)
195     */
196    @DeleteProvider(type = EntitySqlProvider.class, method = "deleteByQuery")
197    int deleteByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
198
199
200    /**
201     * 根据主键来更新数据,若 entity 属性数据为 null,该属性不会新到数据库
202     *
203     * @param entity 数据内容,必须包含有主键
204     * @return 返回影响的行数
205     */
206    default int update(T entity) {
207        return update(entity, true);
208    }
209
210    /**
211     * 根据主键来更新数据到数据库
212     *
213     * @param entity      数据内容
214     * @param ignoreNulls 是否忽略空内容字段
215     * @return 返回影响的行数
216     * @see com.mybatisflex.core.provider.EntitySqlProvider#update(Map, ProviderContext)
217     */
218    @UpdateProvider(type = EntitySqlProvider.class, method = "update")
219    int update(@Param(FlexConsts.ENTITY) T entity, @Param(FlexConsts.IGNORE_NULLS) boolean ignoreNulls);
220
221
222    /**
223     * 根据 map 构建的条件来更新数据
224     *
225     * @param entity 数据
226     * @param map    where 条件内容
227     * @return 返回影响的行数
228     */
229    default int updateByMap(T entity, Map<String, Object> map) {
230        return updateByQuery(entity, QueryWrapper.create().where(map));
231    }
232
233    /**
234     * 根据 condition 来更新数据
235     *
236     * @param entity    数据
237     * @param condition 条件
238     * @return 返回影响的行数
239     */
240    default int updateByCondition(T entity, QueryCondition condition) {
241        return updateByQuery(entity, QueryWrapper.create().where(condition));
242    }
243
244    /**
245     * 根据 condition 来更新数据
246     *
247     * @param entity      数据
248     * @param ignoreNulls 是否忽略 null 数据,默认为 true
249     * @param condition   条件
250     * @return 返回影响的行数
251     */
252    default int updateByCondition(T entity, boolean ignoreNulls, QueryCondition condition) {
253        return updateByQuery(entity, ignoreNulls, QueryWrapper.create().where(condition));
254    }
255
256
257    /**
258     * 根据 query 构建的条件来更新数据
259     *
260     * @param entity       数据内容
261     * @param queryWrapper query 条件
262     * @return 返回影响的行数
263     */
264
265    default int updateByQuery(T entity, QueryWrapper queryWrapper) {
266        return updateByQuery(entity, true, queryWrapper);
267    }
268
269    /**
270     * 根据 query 构建的条件来更新数据
271     *
272     * @param entity       数据内容
273     * @param ignoreNulls  是否忽略空值
274     * @param queryWrapper query 条件
275     * @see com.mybatisflex.core.provider.EntitySqlProvider#updateByQuery(Map, ProviderContext)
276     */
277    @UpdateProvider(type = EntitySqlProvider.class, method = "updateByQuery")
278    int updateByQuery(@Param(FlexConsts.ENTITY) T entity, @Param(FlexConsts.IGNORE_NULLS) boolean ignoreNulls, @Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
279
280
281    /**
282     * 执行类似 update table set field=field+1 where ... 的场景
283     *
284     * @param fieldName    字段名
285     * @param value        值( >=0 加,小于 0 减)
286     * @param queryWrapper 条件
287     * @see EntitySqlProvider#updateNumberAddByQuery(Map, ProviderContext)
288     */
289    @UpdateProvider(type = EntitySqlProvider.class, method = "updateNumberAddByQuery")
290    int updateNumberAddByQuery(@Param(FlexConsts.FIELD_NAME) String fieldName, @Param(FlexConsts.VALUE) Number value, @Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
291
292
293    /**
294     * 执行类似 update table set field=field+1 where ... 的场景
295     *
296     * @param fn           字段名
297     * @param value        值( >=0 加,小于 0 减)
298     * @param queryWrapper 条件
299     * @see EntitySqlProvider#updateNumberAddByQuery(Map, ProviderContext)
300     */
301    default int updateNumberAddByQuery(LambdaGetter<T> fn, Number value, QueryWrapper queryWrapper) {
302        TableInfo tableInfo = TableInfoFactory.ofMapperClass(ClassUtil.getUsefulClass(getClass()));
303        String column = tableInfo.getColumnByProperty(LambdaUtil.getFieldName(fn));
304        return updateNumberAddByQuery(column, value, queryWrapper);
305    }
306
307
308    /**
309     * 根据主键来选择数据
310     *
311     * @param id 多个主键
312     * @return entity
313     * @see com.mybatisflex.core.provider.EntitySqlProvider#selectOneById(Map, ProviderContext)
314     */
315    @SelectProvider(type = EntitySqlProvider.class, method = "selectOneById")
316    T selectOneById(@Param(FlexConsts.PRIMARY_VALUE) Serializable id);
317
318
319    /**
320     * 根据 map 构建的条件来查询数据
321     *
322     * @param whereConditions where 条件
323     * @return entity 数据
324     */
325    default T selectOneByMap(Map<String, Object> whereConditions) {
326        return selectOneByQuery(QueryWrapper.create().where(whereConditions));
327    }
328
329
330    /**
331     * 根据 condition 来查询数据
332     *
333     * @param condition 条件
334     * @return 1 条数据
335     */
336    default T selectOneByCondition(QueryCondition condition) {
337        return selectOneByQuery(QueryWrapper.create().where(condition));
338    }
339
340
341    /**
342     * 根据 queryWrapper 构建的条件来查询 1 条数据
343     *
344     * @param queryWrapper query 条件
345     * @return entity 数据
346     */
347    default T selectOneByQuery(QueryWrapper queryWrapper) {
348        return MapperUtil.getSelectOneResult(selectListByQuery(queryWrapper));
349    }
350
351
352    /**
353     * 根据 queryWrapper 构建的条件来查询 1 条数据
354     *
355     * @param queryWrapper query 条件
356     * @param asType       接收类型
357     * @return 数据内容
358     */
359    default <R> R selectOneByQueryAs(QueryWrapper queryWrapper, Class<R> asType) {
360        return MapperUtil.getSelectOneResult(selectListByQueryAs(queryWrapper, asType));
361    }
362
363    /**
364     * 根据多个主键来查询多条数据
365     *
366     * @param ids 主键列表
367     * @return 数据列表
368     * @see com.mybatisflex.core.provider.EntitySqlProvider#selectListByIds(Map, ProviderContext)
369     */
370    @SelectProvider(type = EntitySqlProvider.class, method = "selectListByIds")
371    List<T> selectListByIds(@Param(FlexConsts.PRIMARY_VALUE) Collection<? extends Serializable> ids);
372
373
374    /**
375     * 根据 map 来构建查询条件,查询多条数据
376     *
377     * @param whereConditions 条件列表
378     * @return 数据列表
379     */
380    default List<T> selectListByMap(Map<String, Object> whereConditions) {
381        return selectListByQuery(QueryWrapper.create().where(whereConditions));
382    }
383
384
385    /**
386     * 根据 map 来构建查询条件,查询多条数据
387     *
388     * @param whereConditions 条件列表
389     * @return 数据列表
390     */
391    default List<T> selectListByMap(Map<String, Object> whereConditions, int count) {
392        return selectListByQuery(QueryWrapper.create().where(whereConditions).limit(count));
393    }
394
395
396    /**
397     * 根据 condition 来查询数据
398     *
399     * @param condition condition 条件
400     * @return 数据列表
401     */
402    default List<T> selectListByCondition(QueryCondition condition) {
403        return selectListByQuery(QueryWrapper.create().where(condition));
404    }
405
406
407    /**
408     * 根据 condition 来查询数据
409     *
410     * @param condition condition 条件
411     * @param count     数据量
412     * @return 数据列表
413     */
414    default List<T> selectListByCondition(QueryCondition condition, int count) {
415        return selectListByQuery(QueryWrapper.create().where(condition).limit(count));
416    }
417
418
419    /**
420     * 根据 query 来构建条件查询数据列表
421     *
422     * @param queryWrapper 查询条件
423     * @return 数据列表
424     * @see com.mybatisflex.core.provider.EntitySqlProvider#selectListByQuery(Map, ProviderContext)
425     */
426    @SelectProvider(type = EntitySqlProvider.class, method = "selectListByQuery")
427    List<T> selectListByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
428
429
430    default List<T> selectListByQuery(QueryWrapper queryWrapper
431            , Consumer<FieldQueryBuilder<T>>... consumers) {
432
433        List<T> list = selectListByQuery(queryWrapper);
434        if (list == null || list.isEmpty()) {
435            return Collections.emptyList();
436        }
437
438        MapperUtil.queryFields(this, list, consumers);
439
440        return list;
441    }
442
443    /**
444     * 根据 query 来构建条件查询游标数据 Cursor
445     * 该方法必须在事务中才能正常使用,非事务下无法获取数据
446     *
447     * @param queryWrapper 查询条件
448     * @return 游标数据 Cursor
449     */
450    @SelectProvider(type = EntitySqlProvider.class, method = "selectListByQuery")
451    Cursor<T> selectCursorByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
452
453
454    /**
455     * 根据 query 来构建条件查询数据列表,要求返回的数据为 asType
456     * 这种场景一般用在 left join 时,有多出了 entity 本身的字段内容,可以转换为 dto、vo 等场景时
457     *
458     * @param queryWrapper 查询条件
459     * @param asType       接收数据类型
460     * @return 数据列表
461     */
462    default <R> List<R> selectListByQueryAs(QueryWrapper queryWrapper, Class<R> asType) {
463        if (Number.class.isAssignableFrom(asType)
464                || String.class == asType) {
465            return selectObjectListByQueryAs(queryWrapper, asType);
466        }
467        try {
468            MappedStatementTypes.setCurrentType(asType);
469            return (List<R>) selectListByQuery(queryWrapper);
470        } finally {
471            MappedStatementTypes.clear();
472        }
473    }
474
475
476    default <R> List<R> selectListByQueryAs(QueryWrapper queryWrapper, Class<R> asType
477            , Consumer<FieldQueryBuilder<R>>... consumers) {
478        List<R> list = selectListByQueryAs(queryWrapper, asType);
479        if (list == null || list.isEmpty()) {
480            return Collections.emptyList();
481        } else {
482            MapperUtil.queryFields(this, list, consumers);
483            return list;
484        }
485    }
486
487
488    /**
489     * 查询全部数据
490     *
491     * @return 数据列表
492     */
493    default List<T> selectAll() {
494        return selectListByQuery(new QueryWrapper());
495    }
496
497
498    /**
499     * 根据 queryWrapper 1 条数据
500     * queryWrapper 执行的结果应该只有 1 列,例如 QueryWrapper.create().select(ACCOUNT.id).where...
501     *
502     * @param queryWrapper 查询包装器
503     * @return 数据量
504     */
505    default Object selectObjectByQuery(QueryWrapper queryWrapper) {
506        return MapperUtil.getSelectOneResult(selectObjectListByQuery(queryWrapper));
507    }
508
509
510    /**
511     * 根据 queryWrapper 来查询数据列表
512     * queryWrapper 执行的结果应该只有 1 列,例如 QueryWrapper.create().select(ACCOUNT.id).where...
513     *
514     * @param queryWrapper 查询包装器
515     * @return 数据列表
516     * @see EntitySqlProvider#selectObjectByQuery(Map, ProviderContext)
517     */
518    @SelectProvider(type = EntitySqlProvider.class, method = "selectObjectByQuery")
519    List<Object> selectObjectListByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
520
521
522    /**
523     * 对 {@link #selectObjectListByQuery(QueryWrapper)} 进行数据转换
524     * 根据 queryWrapper 来查询数据列表
525     * queryWrapper 执行的结果应该只有 1 列,例如 QueryWrapper.create().select(ACCOUNT.id).where...
526     *
527     * @param queryWrapper 查询包装器
528     * @param asType       转换成的数据类型
529     * @return 数据列表
530     */
531    default <R> List<R> selectObjectListByQueryAs(QueryWrapper queryWrapper, Class<R> asType) {
532        List<Object> queryResults = selectObjectListByQuery(queryWrapper);
533        if (queryResults == null || queryResults.isEmpty()) {
534            return Collections.emptyList();
535        }
536        List<R> results = new ArrayList<>(queryResults.size());
537        for (Object queryResult : queryResults) {
538            results.add((R) ConvertUtil.convert(queryResult, asType));
539        }
540        return results;
541    }
542
543
544    /**
545     * 查询数据量
546     *
547     * @param queryWrapper 查询包装器
548     * @return 数据量
549     */
550    default long selectCountByQuery(QueryWrapper queryWrapper) {
551        List<QueryColumn> selectColumns = CPI.getSelectColumns(queryWrapper);
552        try {
553            if (CollectionUtil.isEmpty(selectColumns)) {
554                queryWrapper.select(count());
555            }
556            List<Object> objects = selectObjectListByQuery(queryWrapper);
557            Object object = objects == null || objects.isEmpty() ? null : objects.get(0);
558            if (object == null) {
559                return 0;
560            } else if (object instanceof Number) {
561                return ((Number) object).longValue();
562            } else {
563                throw FlexExceptions.wrap("selectCountByQuery error, Can not get number value for queryWrapper: %s", queryWrapper);
564            }
565        } finally {
566            //fixed https://github.com/mybatis-flex/mybatis-flex/issues/49
567            CPI.setSelectColumns(queryWrapper, selectColumns);
568        }
569    }
570
571
572    /**
573     * 根据条件查询数据总量
574     *
575     * @param condition 条件
576     * @return 数据量
577     */
578    default long selectCountByCondition(QueryCondition condition) {
579        return selectCountByQuery(QueryWrapper.create().where(condition));
580    }
581
582
583    /**
584     * 分页查询
585     *
586     * @param pageNumber   当前页码
587     * @param pageSize     每页的数据量
588     * @param queryWrapper 查询条件
589     * @return 返回 Page 数据
590     */
591    default Page<T> paginate(int pageNumber, int pageSize, QueryWrapper queryWrapper) {
592        Page<T> page = new Page<>(pageNumber, pageSize);
593        return paginate(page, queryWrapper);
594    }
595
596
597    /**
598     * 根据条件分页查询
599     *
600     * @param pageNumber 当前页面
601     * @param pageSize   每页的数据量
602     * @param condition  查询条件
603     * @return 返回 Page 数据
604     */
605    default Page<T> paginate(int pageNumber, int pageSize, QueryCondition condition) {
606        Page<T> page = new Page<>(pageNumber, pageSize);
607        return paginate(page, new QueryWrapper().where(condition));
608    }
609
610    /**
611     * 分页查询
612     *
613     * @param pageNumber   当前页码
614     * @param pageSize     每页的数据量
615     * @param totalRow     数据总量
616     * @param queryWrapper 查询条件
617     * @return 返回 Page 数据
618     */
619    default Page<T> paginate(int pageNumber, int pageSize, int totalRow, QueryWrapper queryWrapper) {
620        Page<T> page = new Page<>(pageNumber, pageSize, totalRow);
621        return paginate(page, queryWrapper);
622    }
623
624
625    /**
626     * 根据条件分页查询
627     *
628     * @param pageNumber 当前页面
629     * @param pageSize   每页的数据量
630     * @param totalRow   数据总量
631     * @param condition  查询条件
632     * @return 返回 Page 数据
633     */
634    default Page<T> paginate(int pageNumber, int pageSize, int totalRow, QueryCondition condition) {
635        Page<T> page = new Page<>(pageNumber, pageSize, totalRow);
636        return paginate(page, new QueryWrapper().where(condition));
637    }
638
639
640    /**
641     * 分页查询
642     *
643     * @param page         page,其包含了页码、每页的数据量,可能包含数据总量
644     * @param queryWrapper 查询条件
645     * @return page 数据
646     */
647    default Page<T> paginate(Page<T> page, QueryWrapper queryWrapper, Consumer<FieldQueryBuilder<T>>... consumers) {
648        return paginateAs(page, queryWrapper, null, consumers);
649    }
650
651
652    default <R> Page<R> paginateAs(Page<R> page, QueryWrapper queryWrapper, Class<R> asType, Consumer<FieldQueryBuilder<R>>... consumers) {
653        List<QueryColumn> selectColumns = CPI.getSelectColumns(queryWrapper);
654        List<QueryOrderBy> orderBys = CPI.getOrderBys(queryWrapper);
655
656        List<Join> joins = CPI.getJoins(queryWrapper);
657        boolean removedJoins = true;
658        // 只有 totalRow 小于 0 的时候才会去查询总量
659        // 这样方便用户做总数缓存,而非每次都要去查询总量
660        // 一般的分页场景中,只有第一页的时候有必要去查询总量,第二页以后是不需要的
661        if (page.getTotalRow() < 0) {
662
663            //移除 select
664            CPI.setSelectColumns(queryWrapper, Collections.singletonList(count().as("total")));
665
666            //移除 OrderBy
667            if (CollectionUtil.isNotEmpty(orderBys)) {
668                CPI.setOrderBys(queryWrapper, null);
669            }
670
671
672            //移除 left join
673            if (joins != null && !joins.isEmpty()) {
674                for (Join join : joins) {
675                    if (!Join.TYPE_LEFT.equals(CPI.getJoinType(join))) {
676                        removedJoins = false;
677                        break;
678                    }
679                }
680            } else {
681                removedJoins = false;
682            }
683
684            if (removedJoins) {
685                List<String> joinTables = new ArrayList<>();
686                joins.forEach(join -> {
687                    QueryTable joinQueryTable = CPI.getJoinQueryTable(join);
688                    if (joinQueryTable != null && StringUtil.isNotBlank(joinQueryTable.getName())) {
689                        joinTables.add(joinQueryTable.getName());
690                    }
691                });
692
693                QueryCondition where = CPI.getWhereQueryCondition(queryWrapper);
694                if (CPI.containsTable(where, CollectionUtil.toArrayString(joinTables))) {
695                    removedJoins = false;
696                }
697            }
698
699            if (removedJoins) {
700                CPI.setJoins(queryWrapper, null);
701            }
702
703
704            long count = selectCountByQuery(queryWrapper);
705            page.setTotalRow(count);
706        }
707
708        if (page.getTotalRow() == 0 || page.getPageNumber() > page.getTotalPage()) {
709            return page;
710        }
711
712        //重置 selectColumns
713        CPI.setSelectColumns(queryWrapper, selectColumns);
714
715        //重置 orderBys
716        if (CollectionUtil.isNotEmpty(orderBys)) {
717            CPI.setOrderBys(queryWrapper, orderBys);
718        }
719
720        //重置 join
721        if (removedJoins) {
722            CPI.setJoins(queryWrapper, joins);
723        }
724
725        int offset = page.getPageSize() * (page.getPageNumber() - 1);
726        queryWrapper.limit(offset, page.getPageSize());
727
728        if (asType != null) {
729            List<R> records = selectListByQueryAs(queryWrapper, asType);
730            MapperUtil.queryFields(this, records, consumers);
731            page.setRecords(records);
732        } else {
733            List<R> records = (List<R>) selectListByQuery(queryWrapper);
734            MapperUtil.queryFields(this, records, consumers);
735            page.setRecords(records);
736        }
737        return page;
738    }
739
740
741}