001/*
002 *  Copyright (c) 2022-2025, 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.constant.FuncName;
019import com.mybatisflex.core.exception.FlexAssert;
020import com.mybatisflex.core.field.FieldQueryBuilder;
021import com.mybatisflex.core.mybatis.MappedStatementTypes;
022import com.mybatisflex.core.paginate.Page;
023import com.mybatisflex.core.provider.EntitySqlProvider;
024import com.mybatisflex.core.query.CPI;
025import com.mybatisflex.core.query.FunctionQueryColumn;
026import com.mybatisflex.core.query.Join;
027import com.mybatisflex.core.query.QueryColumn;
028import com.mybatisflex.core.query.QueryCondition;
029import com.mybatisflex.core.query.QueryWrapper;
030import com.mybatisflex.core.row.Db;
031import com.mybatisflex.core.row.Row;
032import com.mybatisflex.core.table.TableInfo;
033import com.mybatisflex.core.table.TableInfoFactory;
034import com.mybatisflex.core.util.ClassUtil;
035import com.mybatisflex.core.util.CollectionUtil;
036import com.mybatisflex.core.util.ConvertUtil;
037import com.mybatisflex.core.util.MapperUtil;
038import org.apache.ibatis.annotations.DeleteProvider;
039import org.apache.ibatis.annotations.InsertProvider;
040import org.apache.ibatis.annotations.Param;
041import org.apache.ibatis.annotations.SelectProvider;
042import org.apache.ibatis.annotations.UpdateProvider;
043import org.apache.ibatis.builder.annotation.ProviderContext;
044import org.apache.ibatis.cursor.Cursor;
045import org.apache.ibatis.session.ExecutorType;
046import org.apache.ibatis.session.SqlSession;
047import org.apache.ibatis.session.SqlSessionFactory;
048
049import java.io.Serializable;
050import java.util.ArrayList;
051import java.util.Collection;
052import java.util.Collections;
053import java.util.List;
054import java.util.Map;
055import java.util.function.BiConsumer;
056import java.util.function.Consumer;
057
058import static com.mybatisflex.core.query.QueryMethods.count;
059
060/**
061 * 通用 Mapper 接口。
062 *
063 * @param <T> 实体类类型
064 * @author 开源海哥
065 * @author 庄佳彬
066 * @author 闵柳华
067 * @author 王帅
068 * @author yangs
069 * @author lhzsdnu
070 * @author 王超
071 */
072@SuppressWarnings({"varargs", "unchecked", "unused"})
073public interface BaseMapper<T> {
074
075    /**
076     * 默认批量处理切片数量。
077     */
078    int DEFAULT_BATCH_SIZE = 1000;
079
080    // === 增(insert) ===
081
082    /**
083     * 插入实体类数据,不忽略 {@code null} 值。
084     *
085     * @param entity 实体类
086     * @return 受影响的行数
087     */
088    default int insert(T entity) {
089        return insert(entity, false);
090    }
091
092    /**
093     * 插入实体类数据,但是忽略 {@code null} 的数据,只对有值的内容进行插入。
094     * 这样的好处是数据库已经配置了一些默认值,这些默认值才会生效。
095     *
096     * @param entity 实体类
097     * @return 受影响的行数
098     */
099    default int insertSelective(T entity) {
100        return insert(entity, true);
101    }
102
103    /**
104     * 插入实体类数据。
105     *
106     * @param entity      实体类
107     * @param ignoreNulls 是否忽略 {@code null} 值
108     * @return 受影响的行数
109     * @see com.mybatisflex.core.provider.EntitySqlProvider#insert(Map, ProviderContext)
110     */
111    @InsertProvider(type = EntitySqlProvider.class, method = "insert")
112    int insert(@Param(FlexConsts.ENTITY) T entity, @Param(FlexConsts.IGNORE_NULLS) boolean ignoreNulls);
113
114    /**
115     * 插入带有主键的实体类,不忽略 {@code null} 值。
116     *
117     * @param entity 实体类
118     * @return 受影响的行数
119     */
120    default int insertWithPk(T entity) {
121        return insertWithPk(entity, false);
122    }
123
124    /**
125     * 插入带有主键的实体类,忽略 {@code null} 值。
126     *
127     * @param entity 实体类
128     * @return 受影响的行数
129     */
130    default int insertSelectiveWithPk(T entity) {
131        return insertWithPk(entity, true);
132    }
133
134    /**
135     * 带有主键的插入,此时实体类不会经过主键生成器生成主键。
136     *
137     * @param entity      带有主键的实体类
138     * @param ignoreNulls 是否忽略 {@code null} 值
139     * @return 受影响的行数
140     * @see com.mybatisflex.core.provider.EntitySqlProvider#insertWithPk(Map, ProviderContext)
141     */
142    @InsertProvider(type = EntitySqlProvider.class, method = "insertWithPk")
143    int insertWithPk(@Param(FlexConsts.ENTITY) T entity, @Param(FlexConsts.IGNORE_NULLS) boolean ignoreNulls);
144
145    /**
146     * 批量插入实体类数据,只会根据第一条数据来构建插入的字段内容。
147     *
148     * @param entities 插入的数据列表
149     * @return 受影响的行数
150     * @see com.mybatisflex.core.provider.EntitySqlProvider#insertBatch(Map, ProviderContext)
151     * @see com.mybatisflex.core.FlexConsts#METHOD_INSERT_BATCH
152     */
153    @InsertProvider(type = EntitySqlProvider.class, method = FlexConsts.METHOD_INSERT_BATCH)
154    int insertBatch(@Param(FlexConsts.ENTITIES) Collection<T> entities);
155
156    /**
157     * 批量插入实体类数据,按 size 切分。
158     *
159     * @param entities 插入的数据列表
160     * @param size     切分大小
161     * @return 受影响的行数
162     */
163    default int insertBatch(Collection<T> entities, int size) {
164
165        // 让 insertBatch(List<T> entities, int size) 和 insertBatch(List<T> entities) 保持一样的验证行为
166        // https://gitee.com/mybatis-flex/mybatis-flex/issues/I9EGWA
167        FlexAssert.notEmpty(entities, "entities");
168
169        if (size <= 0) {
170            size = DEFAULT_BATCH_SIZE;
171        }
172
173        List<T> entityList = entities instanceof List ? (List<T>) entities : new ArrayList<>(entities);
174
175        int sum = 0;
176        int entitiesSize = entities.size();
177        int maxIndex = entitiesSize / size + (entitiesSize % size == 0 ? 0 : 1);
178        for (int i = 0; i < maxIndex; i++) {
179            List<T> list = entityList.subList(i * size, Math.min(i * size + size, entitiesSize));
180            sum += insertBatch(list);
181        }
182        return sum;
183    }
184
185
186    /**
187     * 批量插入实体类数据,并自动忽略 null 值
188     *
189     * @param entities 插入的数据列表
190     * @return 受影响的行数
191     */
192    default int insertBatchSelective(Collection<T> entities) {
193        return insertBatchSelective(entities, DEFAULT_BATCH_SIZE);
194    }
195
196
197    /**
198     * 批量插入实体类数据,按 size 切分,并自动忽略 null 值
199     *
200     * @param entities 插入的数据列表
201     * @param size     切分大小
202     * @return 受影响的行数
203     */
204    @SuppressWarnings("rawtypes")
205    default int insertBatchSelective(Collection<T> entities, int size) {
206
207        FlexAssert.notEmpty(entities, "entities");
208
209        if (size <= 0) {
210            size = DEFAULT_BATCH_SIZE;
211        }
212
213        Class aClass = ClassUtil.getUsefulClass(this.getClass());
214        int[] batchResults = Db.executeBatch(entities, size, aClass, (BiConsumer<BaseMapper, T>) BaseMapper::insertSelective);
215        int result = 0;
216        for (int anInt : batchResults) {
217            if (anInt > 0) result += anInt;
218        }
219        return result;
220    }
221
222
223    /**
224     * 插入或者更新,若主键有值,则更新,若没有主键值,则插入,插入或者更新都不会忽略 {@code null} 值。
225     *
226     * @param entity 实体类
227     * @return 受影响的行数
228     */
229    default int insertOrUpdate(T entity) {
230        return insertOrUpdate(entity, false);
231    }
232
233    /**
234     * 插入或者更新,若主键有值,则更新,若没有主键值,则插入,插入或者更新都会忽略 {@code null} 值。
235     *
236     * @param entity 实体类
237     * @return 受影响的行数
238     */
239    default int insertOrUpdateSelective(T entity) {
240        return insertOrUpdate(entity, true);
241    }
242
243    /**
244     * 插入或者更新,若主键有值,则更新,若没有主键值,则插入。
245     *
246     * @param entity      实体类
247     * @param ignoreNulls 是否忽略 {@code null} 值
248     * @return 受影响的行数
249     */
250    default int insertOrUpdate(T entity, boolean ignoreNulls) {
251        TableInfo tableInfo = TableInfoFactory.ofEntityClass(entity.getClass());
252        Object[] pkArgs = tableInfo.buildPkSqlArgs(entity);
253        if (pkArgs.length == 0 || pkArgs[0] == null) {
254            return insert(entity, ignoreNulls);
255        } else {
256            return update(entity, ignoreNulls);
257        }
258    }
259
260    // === 删(delete) ===
261
262    /**
263     * 根据实体主键来删除数据。
264     *
265     * @param entity 实体对象,必须包含有主键
266     * @return 受影响的行数
267     */
268    default int delete(T entity) {
269        FlexAssert.notNull(entity, "entity can not be null");
270        TableInfo tableInfo = TableInfoFactory.ofEntityClass(entity.getClass());
271        Object[] pkArgs = tableInfo.buildPkSqlArgs(entity);
272        return deleteById(pkArgs);
273    }
274
275    /**
276     * 根据主键删除数据。如果是多个主键的情况下,需要传入数组,例如:{@code new Integer[]{100,101}}。
277     *
278     * @param id 主键数据
279     * @return 受影响的行数
280     * @see com.mybatisflex.core.provider.EntitySqlProvider#deleteById(Map, ProviderContext)
281     */
282    @DeleteProvider(type = EntitySqlProvider.class, method = "deleteById")
283    int deleteById(@Param(FlexConsts.PRIMARY_VALUE) Serializable id);
284
285    /**
286     * 根据多个主键批量删除数据。
287     *
288     * @param ids 主键列表
289     * @return 受影响的行数
290     * @see com.mybatisflex.core.provider.EntitySqlProvider#deleteBatchByIds(Map, ProviderContext)
291     */
292    @DeleteProvider(type = EntitySqlProvider.class, method = "deleteBatchByIds")
293    int deleteBatchByIds(@Param(FlexConsts.PRIMARY_VALUE) Collection<? extends Serializable> ids);
294
295    /**
296     * 根据多个主键批量删除数据。
297     *
298     * @param ids  主键列表
299     * @param size 切分大小
300     * @return 受影响的行数
301     * @see com.mybatisflex.core.provider.EntitySqlProvider#deleteBatchByIds(Map, ProviderContext)
302     */
303    default int deleteBatchByIds(Collection<? extends Serializable> ids, int size) {
304        if (size <= 0) {
305            size = DEFAULT_BATCH_SIZE;
306        }
307        int sum = 0;
308        int entitiesSize = ids.size();
309        int maxIndex = entitiesSize / size + (entitiesSize % size == 0 ? 0 : 1);
310        List<? extends Serializable> idList = ids instanceof List ? (List<? extends Serializable>) ids : new ArrayList<>(ids);
311        for (int i = 0; i < maxIndex; i++) {
312            List<? extends Serializable> list = idList.subList(i * size, Math.min(i * size + size, entitiesSize));
313            sum += deleteBatchByIds(list);
314        }
315        return sum;
316    }
317
318    /**
319     * 根据 Map 构建的条件来删除数据。
320     *
321     * @param whereConditions 条件
322     * @return 受影响的行数
323     */
324    default int deleteByMap(Map<String, Object> whereConditions) {
325        FlexAssert.notEmpty(whereConditions, "whereConditions");
326        return deleteByQuery(QueryWrapper.create().where(whereConditions));
327    }
328
329    /**
330     * 根据查询条件来删除数据。
331     *
332     * @param whereConditions 条件
333     * @return 受影响的行数
334     */
335    default int deleteByCondition(QueryCondition whereConditions) {
336        FlexAssert.notNull(whereConditions, "whereConditions");
337        return deleteByQuery(QueryWrapper.create().where(whereConditions));
338    }
339
340    /**
341     * 根据查询条件来删除数据。
342     *
343     * @param queryWrapper 条件
344     * @return 受影响的行数
345     * @see com.mybatisflex.core.provider.EntitySqlProvider#deleteByQuery(Map, ProviderContext)
346     */
347    @DeleteProvider(type = EntitySqlProvider.class, method = "deleteByQuery")
348    int deleteByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
349
350    // === 改(update) ===
351
352    /**
353     * 根据主键来更新数据,若实体类属性数据为 {@code null},该属性不会更新到数据库。
354     *
355     * @param entity 数据内容,必须包含有主键
356     * @return 受影响的行数
357     */
358    default int update(T entity) {
359        return update(entity, true);
360    }
361
362    /**
363     * 根据主键来更新数据到数据库。
364     *
365     * @param entity      数据内容,必须包含有主键
366     * @param ignoreNulls 是否忽略空内容字段
367     * @return 受影响的行数
368     * @see com.mybatisflex.core.provider.EntitySqlProvider#update(Map, ProviderContext)
369     */
370    @UpdateProvider(type = EntitySqlProvider.class, method = "update")
371    int update(@Param(FlexConsts.ENTITY) T entity, @Param(FlexConsts.IGNORE_NULLS) boolean ignoreNulls);
372
373    /**
374     * 根据 Map 构建的条件来更新数据。
375     *
376     * @param entity          实体类
377     * @param whereConditions 条件
378     * @return 受影响的行数
379     */
380    default int updateByMap(T entity, Map<String, Object> whereConditions) {
381        FlexAssert.notEmpty(whereConditions, "whereConditions");
382        return updateByQuery(entity, QueryWrapper.create().where(whereConditions));
383    }
384
385    /**
386     * 根据 Map 构建的条件来更新数据。
387     *
388     * @param entity          实体类
389     * @param ignoreNulls     是否忽略 {@code null} 数据
390     * @param whereConditions 条件
391     * @return 受影响的行数
392     */
393    default int updateByMap(T entity, boolean ignoreNulls, Map<String, Object> whereConditions) {
394        FlexAssert.notEmpty(whereConditions, "whereConditions");
395        return updateByQuery(entity, ignoreNulls, QueryWrapper.create().where(whereConditions));
396    }
397
398    /**
399     * 根据查询条件来更新数据。
400     *
401     * @param entity          实体类
402     * @param whereConditions 条件
403     * @return 受影响的行数
404     */
405    default int updateByCondition(T entity, QueryCondition whereConditions) {
406        FlexAssert.notNull(whereConditions, "whereConditions");
407        return updateByQuery(entity, QueryWrapper.create().where(whereConditions));
408    }
409
410    /**
411     * 根据查询条件来更新数据。
412     *
413     * @param entity          实体类
414     * @param ignoreNulls     是否忽略 {@code null} 数据
415     * @param whereConditions 条件
416     * @return 受影响的行数
417     */
418    default int updateByCondition(T entity, boolean ignoreNulls, QueryCondition whereConditions) {
419        FlexAssert.notNull(whereConditions, "whereConditions");
420        return updateByQuery(entity, ignoreNulls, QueryWrapper.create().where(whereConditions));
421    }
422
423    /**
424     * 根据查询条件来更新数据。
425     *
426     * @param entity       实体类
427     * @param queryWrapper 条件
428     * @return 受影响的行数
429     */
430    default int updateByQuery(T entity, QueryWrapper queryWrapper) {
431        return updateByQuery(entity, true, queryWrapper);
432    }
433
434    /**
435     * 根据查询条件来更新数据。
436     *
437     * @param entity       实体类
438     * @param ignoreNulls  是否忽略空值
439     * @param queryWrapper 条件
440     * @return 受影响的行数
441     * @see com.mybatisflex.core.provider.EntitySqlProvider#updateByQuery(Map, ProviderContext)
442     */
443    @UpdateProvider(type = EntitySqlProvider.class, method = "updateByQuery")
444    int updateByQuery(@Param(FlexConsts.ENTITY) T entity, @Param(FlexConsts.IGNORE_NULLS) boolean ignoreNulls, @Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
445
446
447    // === 查(select) ===
448
449    /**
450     * 根据实体主键查询数据。
451     *
452     * @param entity 实体对象,必须包含有主键
453     * @return 实体类数据
454     */
455    default T selectOneByEntityId(T entity) {
456        FlexAssert.notNull(entity, "entity can not be null");
457        TableInfo tableInfo = TableInfoFactory.ofEntityClass(entity.getClass());
458        Object[] pkArgs = tableInfo.buildPkSqlArgs(entity);
459        return selectOneById(pkArgs);
460    }
461
462    /**
463     * 根据主键查询数据。
464     *
465     * @param id 主键
466     * @return 实体类数据
467     * @see com.mybatisflex.core.provider.EntitySqlProvider#selectOneById(Map, ProviderContext)
468     */
469    @SelectProvider(type = EntitySqlProvider.class, method = "selectOneById")
470    T selectOneById(@Param(FlexConsts.PRIMARY_VALUE) Serializable id);
471
472    /**
473     * 根据 Map 构建的条件来查询数据。
474     *
475     * @param whereConditions 条件
476     * @return 实体类数据
477     */
478    default T selectOneByMap(Map<String, Object> whereConditions) {
479        FlexAssert.notEmpty(whereConditions, "whereConditions");
480        return selectOneByQuery(QueryWrapper.create().where(whereConditions));
481    }
482
483    /**
484     * 根据查询条件查询数据。
485     *
486     * @param whereConditions 条件
487     * @return 实体类数据
488     */
489    default T selectOneByCondition(QueryCondition whereConditions) {
490        FlexAssert.notNull(whereConditions, "whereConditions");
491        return selectOneByQuery(QueryWrapper.create().where(whereConditions));
492    }
493
494    /**
495     * 根据查询条件来查询 1 条数据。
496     *
497     * @param queryWrapper 条件
498     * @return 实体类数据
499     */
500    default T selectOneByQuery(QueryWrapper queryWrapper) {
501        List<Join> joins = CPI.getJoins(queryWrapper);
502        if (CollectionUtil.isNotEmpty(joins)) {
503            return MapperUtil.getSelectOneResult(selectListByQuery(queryWrapper));
504        }
505        Long limitRows = CPI.getLimitRows(queryWrapper);
506        try {
507            queryWrapper.limit(1);
508            return MapperUtil.getSelectOneResult(selectListByQuery(queryWrapper));
509        } finally {
510            CPI.setLimitRows(queryWrapper, limitRows);
511        }
512    }
513
514    /**
515     * 根据查询条件来查询 1 条数据。
516     *
517     * @param queryWrapper 条件
518     * @param asType       接收数据类型
519     * @return 实体类数据
520     */
521    default <R> R selectOneByQueryAs(QueryWrapper queryWrapper, Class<R> asType) {
522        List<Join> joins = CPI.getJoins(queryWrapper);
523        if (CollectionUtil.isNotEmpty(joins)) {
524            return MapperUtil.getSelectOneResult(selectListByQueryAs(queryWrapper, asType));
525        }
526        Long limitRows = CPI.getLimitRows(queryWrapper);
527        try {
528            queryWrapper.limit(1);
529            return MapperUtil.getSelectOneResult(selectListByQueryAs(queryWrapper, asType));
530        } finally {
531            CPI.setLimitRows(queryWrapper, limitRows);
532        }
533    }
534
535    /**
536     * 根据 Map 构建的条件来查询 1 条数据。
537     *
538     * @param whereConditions 条件
539     * @return 实体类数据
540     */
541    default T selectOneWithRelationsByMap(Map<String, Object> whereConditions) {
542        FlexAssert.notEmpty(whereConditions, "whereConditions");
543        return selectOneWithRelationsByQuery(QueryWrapper.create().where(whereConditions));
544    }
545
546    /**
547     * 根据查询条件查询 1 条数据。
548     *
549     * @param whereConditions 条件
550     * @return 实体类数据
551     */
552    default T selectOneWithRelationsByCondition(QueryCondition whereConditions) {
553        FlexAssert.notNull(whereConditions, "whereConditions");
554        return selectOneWithRelationsByQuery(QueryWrapper.create().where(whereConditions));
555    }
556
557    /**
558     * 根据查询条件来查询 1 条数据。
559     *
560     * @param queryWrapper 条件
561     * @return 实体类数据
562     */
563    default T selectOneWithRelationsByQuery(QueryWrapper queryWrapper) {
564        List<Join> joins = CPI.getJoins(queryWrapper);
565        if (CollectionUtil.isNotEmpty(joins)) {
566            return MapperUtil.queryRelations(this, MapperUtil.getSelectOneResult(selectListByQuery(queryWrapper)));
567        }
568        Long limitRows = CPI.getLimitRows(queryWrapper);
569        try {
570            queryWrapper.limit(1);
571            return MapperUtil.queryRelations(this, MapperUtil.getSelectOneResult(selectListByQuery(queryWrapper)));
572        } finally {
573            CPI.setLimitRows(queryWrapper, limitRows);
574        }
575    }
576
577    /**
578     * 根据主表主键来查询 1 条数据。
579     *
580     * @param id 主表主键
581     * @return 实体类数据
582     */
583    default T selectOneWithRelationsById(Serializable id) {
584        return MapperUtil.queryRelations(this, selectOneById(id));
585    }
586
587    /**
588     * 根据主表主键来查询 1 条数据。
589     *
590     * @param id     表主键
591     * @param asType 接收数据类型
592     * @return 实体类数据
593     */
594    default <R> R selectOneWithRelationsByIdAs(Serializable id, Class<R> asType) {
595        R result;
596        try {
597            MappedStatementTypes.setCurrentType(asType);
598            result = (R) selectOneById(id);
599        } finally {
600            MappedStatementTypes.clear();
601        }
602        return MapperUtil.queryRelations(this, result);
603    }
604
605    /**
606     * 根据查询条件来查询 1 条数据。
607     *
608     * @param queryWrapper 条件
609     * @param asType       接收数据类型
610     * @return 实体类数据
611     */
612    default <R> R selectOneWithRelationsByQueryAs(QueryWrapper queryWrapper, Class<R> asType) {
613        List<Join> joins = CPI.getJoins(queryWrapper);
614        if (CollectionUtil.isNotEmpty(joins)) {
615            return MapperUtil.queryRelations(this, MapperUtil.getSelectOneResult(selectListByQueryAs(queryWrapper, asType)));
616        }
617        Long limitRows = CPI.getLimitRows(queryWrapper);
618        try {
619            queryWrapper.limit(1);
620            return MapperUtil.queryRelations(this, MapperUtil.getSelectOneResult(selectListByQueryAs(queryWrapper, asType)));
621        } finally {
622            CPI.setLimitRows(queryWrapper, limitRows);
623        }
624    }
625
626    /**
627     * 根据多个主键来查询多条数据。
628     *
629     * @param ids 主键列表
630     * @return 数据列表
631     * @see com.mybatisflex.core.provider.EntitySqlProvider#selectListByIds(Map, ProviderContext)
632     */
633    @SelectProvider(type = EntitySqlProvider.class, method = "selectListByIds")
634    List<T> selectListByIds(@Param(FlexConsts.PRIMARY_VALUE) Collection<? extends Serializable> ids);
635
636    /**
637     * 根据 Map 来构建查询条件,查询多条数据。
638     *
639     * @param whereConditions 条件
640     * @return 数据列表
641     */
642    default List<T> selectListByMap(Map<String, Object> whereConditions) {
643        FlexAssert.notEmpty(whereConditions, "whereConditions");
644        return selectListByQuery(QueryWrapper.create().where(whereConditions));
645    }
646
647    /**
648     * 根据 Map 来构建查询条件,查询多条数据。
649     *
650     * @param whereConditions 条件
651     * @param count           数据量
652     * @return 数据列表
653     */
654    default List<T> selectListByMap(Map<String, Object> whereConditions, Long count) {
655        FlexAssert.notEmpty(whereConditions, "whereConditions");
656        return selectListByQuery(QueryWrapper.create().where(whereConditions).limit(count));
657    }
658
659    /**
660     * 根据查询条件查询多条数据。
661     *
662     * @param whereConditions 条件
663     * @return 数据列表
664     */
665    default List<T> selectListByCondition(QueryCondition whereConditions) {
666        FlexAssert.notNull(whereConditions, "whereConditions");
667        return selectListByQuery(QueryWrapper.create().where(whereConditions));
668    }
669
670    /**
671     * 根据查询条件查询多条数据。
672     *
673     * @param whereConditions 条件
674     * @param count           数据量
675     * @return 数据列表
676     */
677    default List<T> selectListByCondition(QueryCondition whereConditions, Long count) {
678        FlexAssert.notNull(whereConditions, "whereConditions");
679        return selectListByQuery(QueryWrapper.create().where(whereConditions).limit(count));
680    }
681
682    /**
683     * 根据查询条件查询数据列表。
684     *
685     * @param queryWrapper 条件
686     * @return 数据列表
687     * @see com.mybatisflex.core.provider.EntitySqlProvider#selectListByQuery(Map, ProviderContext)
688     */
689    @SelectProvider(type = EntitySqlProvider.class, method = "selectListByQuery")
690    List<T> selectListByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
691
692    /**
693     * 根据查询条件查询数据列表。
694     *
695     * @param queryWrapper 条件
696     * @param consumers    字段查询
697     * @return 数据列表
698     */
699    default List<T> selectListByQuery(QueryWrapper queryWrapper, Consumer<FieldQueryBuilder<T>>... consumers) {
700        List<T> list = selectListByQuery(queryWrapper);
701        if (list == null || list.isEmpty()) {
702            return Collections.emptyList();
703        }
704        MapperUtil.queryFields(this, list, consumers);
705        return list;
706    }
707
708    /**
709     * 根据查询条件查询游标数据,该方法必须在事务中才能正常使用,非事务下无法获取数据。
710     *
711     * @param queryWrapper 条件
712     * @return 游标数据
713     */
714    @SelectProvider(type = EntitySqlProvider.class, method = "selectListByQuery")
715    Cursor<T> selectCursorByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
716
717    /**
718     * 根据查询条件查询游标数据,要求返回的数据为 asType 类型。该方法必须在事务中才能正常使用,非事务下无法获取数据。
719     *
720     * @param queryWrapper 条件
721     * @param asType       接收的数据类型
722     * @return 游标数据
723     */
724    default <R> Cursor<R> selectCursorByQueryAs(QueryWrapper queryWrapper, Class<R> asType) {
725        try {
726            MappedStatementTypes.setCurrentType(asType);
727            return (Cursor<R>) selectCursorByQuery(queryWrapper);
728        } finally {
729            MappedStatementTypes.clear();
730        }
731    }
732
733    /**
734     * 根据查询条件查询 Row 数据。
735     *
736     * @param queryWrapper 条件
737     * @return 行数据
738     */
739    @SelectProvider(type = EntitySqlProvider.class, method = "selectListByQuery")
740    List<Row> selectRowsByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
741
742    /**
743     * 根据查询条件查询数据列表,要求返回的数据为 asType。这种场景一般用在 left join 时,
744     * 有多出了实体类本身的字段内容,可以转换为 dto、vo 等场景。
745     *
746     * @param queryWrapper 条件
747     * @param asType       接收数据类型
748     * @return 数据列表
749     */
750    default <R> List<R> selectListByQueryAs(QueryWrapper queryWrapper, Class<R> asType) {
751        if (Number.class.isAssignableFrom(asType)
752            || String.class == asType) {
753            return selectObjectListByQueryAs(queryWrapper, asType);
754        }
755
756        if (Map.class.isAssignableFrom(asType)) {
757            return (List<R>) selectRowsByQuery(queryWrapper);
758        }
759
760        try {
761            MappedStatementTypes.setCurrentType(asType);
762            return (List<R>) selectListByQuery(queryWrapper);
763        } finally {
764            MappedStatementTypes.clear();
765        }
766    }
767
768    /**
769     * 根据查询条件查询数据列表,要求返回的数据为 asType 类型。
770     *
771     * @param queryWrapper 条件
772     * @param asType       接收的数据类型
773     * @param consumers    字段查询
774     * @return 数据列表
775     */
776    default <R> List<R> selectListByQueryAs(QueryWrapper queryWrapper, Class<R> asType, Consumer<FieldQueryBuilder<R>>... consumers) {
777        List<R> list = selectListByQueryAs(queryWrapper, asType);
778        if (list == null || list.isEmpty()) {
779            return Collections.emptyList();
780        } else {
781            MapperUtil.queryFields(this, list, consumers);
782            return list;
783        }
784    }
785
786    /**
787     * 查询实体类及其 Relation 注解字段。
788     *
789     * @param queryWrapper 条件
790     */
791    default List<T> selectListWithRelationsByQuery(QueryWrapper queryWrapper) {
792        return MapperUtil.queryRelations(this, selectListByQuery(queryWrapper));
793    }
794
795    /**
796     * 查询实体类及其 Relation 注解字段。
797     *
798     * @param queryWrapper 条件
799     * @param asType       要求返回的数据类型
800     * @return 数据列表
801     */
802    default <R> List<R> selectListWithRelationsByQueryAs(QueryWrapper queryWrapper, Class<R> asType) {
803        if (Number.class.isAssignableFrom(asType)
804            || String.class == asType) {
805            return selectObjectListByQueryAs(queryWrapper, asType);
806        }
807
808        if (Map.class.isAssignableFrom(asType)) {
809            return (List<R>) selectRowsByQuery(queryWrapper);
810        }
811
812        List<T> result;
813        try {
814            MappedStatementTypes.setCurrentType(asType);
815            result = selectListByQuery(queryWrapper);
816        } finally {
817            MappedStatementTypes.clear();
818        }
819        return MapperUtil.queryRelations(this, (List<R>) result);
820    }
821
822    /**
823     * 查询实体类及其 Relation 注解字段。
824     *
825     * @param queryWrapper 条件
826     * @param asType       返回的类型
827     * @param consumers    字段查询
828     * @return 数据列表
829     */
830    default <R> List<R> selectListWithRelationsByQueryAs(QueryWrapper queryWrapper, Class<R> asType, Consumer<FieldQueryBuilder<R>>... consumers) {
831        List<R> list = selectListByQueryAs(queryWrapper, asType);
832        if (list == null || list.isEmpty()) {
833            return Collections.emptyList();
834        } else {
835            MapperUtil.queryRelations(this, list);
836            MapperUtil.queryFields(this, list, consumers);
837            return list;
838        }
839    }
840
841    /**
842     * 查询全部数据。
843     *
844     * @return 数据列表
845     */
846    default List<T> selectAll() {
847        return selectListByQuery(new QueryWrapper());
848    }
849
850    /**
851     * 查询全部数据,及其 Relation 字段内容。
852     *
853     * @return 数据列表
854     */
855    default List<T> selectAllWithRelations() {
856        return MapperUtil.queryRelations(this, selectListByQuery(new QueryWrapper()));
857    }
858
859    /**
860     * 查询第一列返回的数据,QueryWrapper 执行的结果应该只有 1 列,例如:<br>
861     * {@code QueryWrapper.create().select(ACCOUNT.id).where(...);}
862     *
863     * @param queryWrapper 查询包装器
864     * @return 数据量
865     */
866    default Object selectObjectByQuery(QueryWrapper queryWrapper) {
867        return MapperUtil.getSelectOneResult(selectObjectListByQuery(queryWrapper));
868    }
869
870    /**
871     * 查询第一列返回的数据,QueryWrapper 执行的结果应该只有 1 列,例如:<br>
872     * {@code QueryWrapper.create().select(ACCOUNT.id).where(...);}
873     *
874     * @param queryWrapper 查询包装器
875     * @param asType       转换成的数据类型
876     * @return 数据量
877     */
878    default <R> R selectObjectByQueryAs(QueryWrapper queryWrapper, Class<R> asType) {
879        return MapperUtil.getSelectOneResult(selectObjectListByQueryAs(queryWrapper, asType));
880    }
881
882    /**
883     * 查询第一列返回的数据集合,QueryWrapper 执行的结果应该只有 1 列,例如:<br>
884     * {@code QueryWrapper.create().select(ACCOUNT.id).where(...);}
885     *
886     * @param queryWrapper 查询包装器
887     * @return 数据列表
888     * @see EntitySqlProvider#selectObjectByQuery(Map, ProviderContext)
889     */
890    @SelectProvider(type = EntitySqlProvider.class, method = "selectObjectByQuery")
891    List<Object> selectObjectListByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
892
893    /**
894     * 查询第一列返回的数据集合,QueryWrapper 执行的结果应该只有 1 列,例如:<br>
895     * {@code QueryWrapper.create().select(ACCOUNT.id).where(...);}
896     *
897     * @param queryWrapper 查询包装器
898     * @param asType       转换成的数据类型
899     * @return 数据列表
900     */
901    default <R> List<R> selectObjectListByQueryAs(QueryWrapper queryWrapper, Class<R> asType) {
902        List<Object> queryResults = selectObjectListByQuery(queryWrapper);
903        if (queryResults == null || queryResults.isEmpty()) {
904            return Collections.emptyList();
905        }
906        List<R> results = new ArrayList<>(queryResults.size());
907        for (Object queryResult : queryResults) {
908            results.add((R) ConvertUtil.convert(queryResult, asType));
909        }
910        return results;
911    }
912
913    /**
914     * 查询数据量。
915     *
916     * @param queryWrapper 条件
917     * @return 数据量
918     */
919    default long selectCountByQuery(QueryWrapper queryWrapper) {
920        List<QueryColumn> selectColumns = CPI.getSelectColumns(queryWrapper);
921        try {
922            List<Object> objects;
923            if (CollectionUtil.isEmpty(selectColumns)) {
924                // 未设置 COUNT(...) 列,默认使用 COUNT(*) 查询
925                queryWrapper.select(count());
926                objects = selectObjectListByQuery(queryWrapper);
927            } else if (selectColumns.get(0) instanceof FunctionQueryColumn) {
928                // COUNT 函数必须在第一列
929                if (!FuncName.COUNT.equalsIgnoreCase(
930                    ((FunctionQueryColumn) selectColumns.get(0)).getFnName()
931                )) {
932                    // 第一个查询列不是 COUNT 函数,使用 COUNT(*) 替换所有的查询列
933                    CPI.setSelectColumns(queryWrapper, Collections.singletonList(count()));
934                }
935                // 第一个查询列是 COUNT 函数,可以使用 COUNT(1)、COUNT(列名) 代替默认的 COUNT(*)
936                objects = selectObjectListByQuery(queryWrapper);
937            } else {
938                // 查询列中的第一列不是 COUNT 函数
939                if (MapperUtil.hasDistinct(selectColumns)) {
940                    // 查询列中包含 DISTINCT 去重
941                    // 使用子查询 SELECT COUNT(*) FROM (SELECT DISTINCT ...) AS `t`
942                    objects = selectObjectListByQuery(MapperUtil.rawCountQueryWrapper(queryWrapper));
943                } else {
944                    // 使用 COUNT(*) 替换所有的查询列
945                    CPI.setSelectColumns(queryWrapper, Collections.singletonList(count()));
946                    objects = selectObjectListByQuery(queryWrapper);
947                }
948            }
949            return MapperUtil.getLongNumber(objects);
950        } finally {
951            // fixed https://github.com/mybatis-flex/mybatis-flex/issues/49
952            CPI.setSelectColumns(queryWrapper, selectColumns);
953        }
954    }
955
956    /**
957     * 根据条件查询数据总量。
958     *
959     * @param whereConditions 条件
960     * @return 数据量
961     */
962    default long selectCountByCondition(QueryCondition whereConditions) {
963        FlexAssert.notNull(whereConditions, "whereConditions");
964        return selectCountByQuery(QueryWrapper.create().where(whereConditions));
965    }
966
967    /**
968     * 分页查询。
969     *
970     * @param pageNumber   当前页码
971     * @param pageSize     每页的数据量
972     * @param queryWrapper 条件
973     * @return 分页数据
974     */
975    default Page<T> paginate(Number pageNumber, Number pageSize, QueryWrapper queryWrapper) {
976        Page<T> page = new Page<>(pageNumber, pageSize);
977        return paginate(page, queryWrapper);
978    }
979
980    /**
981     * 分页查询,及其 Relation 字段内容。
982     *
983     * @param pageNumber   当前页码
984     * @param pageSize     每页的数据量
985     * @param queryWrapper 条件
986     * @return 分页数据
987     */
988    default Page<T> paginateWithRelations(Number pageNumber, Number pageSize, QueryWrapper queryWrapper) {
989        Page<T> page = new Page<>(pageNumber, pageSize);
990        return paginateWithRelations(page, queryWrapper);
991    }
992
993    /**
994     * 分页查询。
995     *
996     * @param pageNumber      当前页码
997     * @param pageSize        每页的数据量
998     * @param whereConditions 条件
999     * @return 分页数据
1000     */
1001    default Page<T> paginate(Number pageNumber, Number pageSize, QueryCondition whereConditions) {
1002        Page<T> page = new Page<>(pageNumber, pageSize);
1003        return paginate(page, new QueryWrapper().where(whereConditions));
1004    }
1005
1006    /**
1007     * 分页查询,及其 Relation 字段内容。
1008     *
1009     * @param pageNumber      当前页码
1010     * @param pageSize        每页的数据量
1011     * @param whereConditions 条件
1012     * @return 分页数据
1013     */
1014    default Page<T> paginateWithRelations(Number pageNumber, Number pageSize, QueryCondition whereConditions) {
1015        Page<T> page = new Page<>(pageNumber, pageSize);
1016        return paginateWithRelations(page, new QueryWrapper().where(whereConditions));
1017    }
1018
1019    /**
1020     * 分页查询。
1021     *
1022     * @param pageNumber   当前页码
1023     * @param pageSize     每页的数据量
1024     * @param totalRow     数据总量
1025     * @param queryWrapper 条件
1026     * @return 分页数据
1027     */
1028    default Page<T> paginate(Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper) {
1029        Page<T> page = new Page<>(pageNumber, pageSize, totalRow);
1030        return paginate(page, queryWrapper);
1031    }
1032
1033    /**
1034     * 分页查询,及其 Relation 字段内容。
1035     *
1036     * @param pageNumber   当前页码
1037     * @param pageSize     每页的数据量
1038     * @param totalRow     数据总量
1039     * @param queryWrapper 条件
1040     * @return 分页数据
1041     */
1042    default Page<T> paginateWithRelations(Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper) {
1043        Page<T> page = new Page<>(pageNumber, pageSize, totalRow);
1044        return paginateWithRelations(page, queryWrapper);
1045    }
1046
1047    /**
1048     * 分页查询。
1049     *
1050     * @param pageNumber      当前页码
1051     * @param pageSize        每页的数据量
1052     * @param totalRow        数据总量
1053     * @param whereConditions 条件
1054     * @return 分页数据
1055     */
1056    default Page<T> paginate(Number pageNumber, Number pageSize, Number totalRow, QueryCondition whereConditions) {
1057        FlexAssert.notNull(whereConditions, "whereConditions");
1058        Page<T> page = new Page<>(pageNumber, pageSize, totalRow);
1059        return paginate(page, new QueryWrapper().where(whereConditions));
1060    }
1061
1062    /**
1063     * 分页查询,及其 Relation 字段内容。
1064     *
1065     * @param pageNumber      当前页码
1066     * @param pageSize        每页的数据量
1067     * @param totalRow        数据总量
1068     * @param whereConditions 条件
1069     * @return 分页数据
1070     */
1071    default Page<T> paginateWithRelations(Number pageNumber, Number pageSize, Number totalRow, QueryCondition whereConditions) {
1072        FlexAssert.notNull(whereConditions, "whereConditions");
1073        Page<T> page = new Page<>(pageNumber, pageSize, totalRow);
1074        return paginateWithRelations(page, new QueryWrapper().where(whereConditions));
1075    }
1076
1077    /**
1078     * 分页查询。
1079     *
1080     * @param page         包含了页码、每页的数据量,可能包含数据总量
1081     * @param queryWrapper 条件
1082     * @return page 数据
1083     */
1084    default Page<T> paginate(Page<T> page, QueryWrapper queryWrapper) {
1085        return paginateAs(page, queryWrapper, null);
1086    }
1087
1088    /**
1089     * 分页查询。
1090     *
1091     * @param page         包含了页码、每页的数据量,可能包含数据总量
1092     * @param queryWrapper 条件
1093     * @param consumers    字段查询
1094     * @return page 数据
1095     */
1096    default Page<T> paginate(Page<T> page, QueryWrapper queryWrapper, Consumer<FieldQueryBuilder<T>>... consumers) {
1097        return paginateAs(page, queryWrapper, null, consumers);
1098    }
1099
1100    /**
1101     * 分页查询,及其 Relation 字段内容。
1102     *
1103     * @param page         包含了页码、每页的数据量,可能包含数据总量
1104     * @param queryWrapper 条件
1105     * @return 分页数据
1106     */
1107    default Page<T> paginateWithRelations(Page<T> page, QueryWrapper queryWrapper) {
1108        return paginateWithRelationsAs(page, queryWrapper, null);
1109    }
1110
1111    /**
1112     * 分页查询,及其 Relation 字段内容。
1113     *
1114     * @param page         包含了页码、每页的数据量,可能包含数据总量
1115     * @param queryWrapper 条件
1116     * @param consumers    字段查询
1117     * @return 分页数据
1118     */
1119    default Page<T> paginateWithRelations(Page<T> page, QueryWrapper queryWrapper, Consumer<FieldQueryBuilder<T>>... consumers) {
1120        return paginateWithRelationsAs(page, queryWrapper, null, consumers);
1121    }
1122
1123    /**
1124     * 分页查询。
1125     *
1126     * @param pageNumber   当前页码
1127     * @param pageSize     每页的数据量
1128     * @param queryWrapper 条件
1129     * @param asType       接收数据类型
1130     * @return 分页数据
1131     */
1132    default <R> Page<R> paginateAs(Number pageNumber, Number pageSize, QueryWrapper queryWrapper, Class<R> asType) {
1133        Page<R> page = new Page<>(pageNumber, pageSize);
1134        return MapperUtil.doPaginate(this, page, queryWrapper, asType, false);
1135    }
1136
1137    /**
1138     * 分页查询。
1139     *
1140     * @param pageNumber   当前页码
1141     * @param pageSize     每页的数据量
1142     * @param totalRow     数据总量
1143     * @param queryWrapper 条件
1144     * @param asType       接收数据类型
1145     * @return 分页数据
1146     */
1147    default <R> Page<R> paginateAs(Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper, Class<R> asType) {
1148        Page<R> page = new Page<>(pageNumber, pageSize, totalRow);
1149        return MapperUtil.doPaginate(this, page, queryWrapper, asType, false);
1150    }
1151
1152    /**
1153     * 分页查询。
1154     *
1155     * @param page         包含了页码、每页的数据量,可能包含数据总量
1156     * @param queryWrapper 条件
1157     * @param asType       接收数据类型
1158     * @return 分页数据
1159     */
1160    default <R> Page<R> paginateAs(Page<R> page, QueryWrapper queryWrapper, Class<R> asType) {
1161        return MapperUtil.doPaginate(this, page, queryWrapper, asType, false);
1162    }
1163
1164    /**
1165     * 分页查询。
1166     *
1167     * @param page         包含了页码、每页的数据量,可能包含数据总量
1168     * @param queryWrapper 条件
1169     * @param asType       接收数据类型
1170     * @param consumers    字段查询
1171     * @return 分页数据
1172     */
1173    default <R> Page<R> paginateAs(Page<R> page, QueryWrapper queryWrapper, Class<R> asType, Consumer<FieldQueryBuilder<R>>... consumers) {
1174        return MapperUtil.doPaginate(this, page, queryWrapper, asType, false, consumers);
1175    }
1176
1177    /**
1178     * 分页查询,及其 Relation 字段内容。
1179     *
1180     * @param pageNumber   当前页码
1181     * @param pageSize     每页的数据量
1182     * @param queryWrapper 条件
1183     * @param asType       接收数据类型
1184     * @return 分页数据
1185     */
1186    default <R> Page<R> paginateWithRelationsAs(Number pageNumber, Number pageSize, QueryWrapper queryWrapper, Class<R> asType) {
1187        Page<R> page = new Page<>(pageNumber, pageSize);
1188        return MapperUtil.doPaginate(this, page, queryWrapper, asType, true);
1189    }
1190
1191    /**
1192     * 分页查询,及其 Relation 字段内容。
1193     *
1194     * @param pageNumber   当前页码
1195     * @param pageSize     每页的数据量
1196     * @param totalRow     数据总量
1197     * @param queryWrapper 条件
1198     * @param asType       接收数据类型
1199     * @return 分页数据
1200     */
1201    default <R> Page<R> paginateWithRelationsAs(Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper, Class<R> asType) {
1202        Page<R> page = new Page<>(pageNumber, pageSize, totalRow);
1203        return MapperUtil.doPaginate(this, page, queryWrapper, asType, true);
1204    }
1205
1206    /**
1207     * 分页查询,及其 Relation 字段内容。
1208     *
1209     * @param page         包含了页码、每页的数据量,可能包含数据总量
1210     * @param queryWrapper 条件
1211     * @param asType       接收数据类型
1212     * @return 分页数据
1213     */
1214    default <R> Page<R> paginateWithRelationsAs(Page<R> page, QueryWrapper queryWrapper, Class<R> asType) {
1215        return MapperUtil.doPaginate(this, page, queryWrapper, asType, true);
1216    }
1217
1218    /**
1219     * 分页查询,及其 Relation 字段内容。
1220     *
1221     * @param page         包含了页码、每页的数据量,可能包含数据总量
1222     * @param queryWrapper 条件
1223     * @param asType       接收数据类型
1224     * @param consumers    字段查询
1225     * @return 分页数据
1226     */
1227    default <R> Page<R> paginateWithRelationsAs(Page<R> page, QueryWrapper queryWrapper, Class<R> asType, Consumer<FieldQueryBuilder<R>>... consumers) {
1228        return MapperUtil.doPaginate(this, page, queryWrapper, asType, true, consumers);
1229    }
1230
1231
1232    default <E> Page<E> xmlPaginate(String dataSelectId, Page<E> page, QueryWrapper queryWrapper) {
1233        return xmlPaginate(dataSelectId, dataSelectId + "_COUNT", page, queryWrapper, null);
1234    }
1235
1236    default <E> Page<E> xmlPaginate(String dataSelectId, Page<E> page, Map<String, Object> otherParams) {
1237        return xmlPaginate(dataSelectId, dataSelectId + "_COUNT", page, null, otherParams);
1238    }
1239
1240    default <E> Page<E> xmlPaginate(String dataSelectId, Page<E> page, QueryWrapper queryWrapper, Map<String, Object> otherParams) {
1241        return xmlPaginate(dataSelectId, dataSelectId + "_COUNT", page, queryWrapper, otherParams);
1242    }
1243
1244    default <E> Page<E> xmlPaginate(String dataSelectId, String countSelectId, Page<E> page, QueryWrapper queryWrapper, Map<String, Object> otherParams) {
1245        SqlSessionFactory sqlSessionFactory = FlexGlobalConfig.getDefaultConfig().getSqlSessionFactory();
1246        ExecutorType executorType = FlexGlobalConfig.getDefaultConfig().getConfiguration().getDefaultExecutorType();
1247        String mapperClassName = ClassUtil.getUsefulClass(this.getClass()).getName();
1248
1249        Map<String, Object> preparedParams = MapperUtil.preparedParams(this, page, queryWrapper, otherParams);
1250        if (!dataSelectId.contains(".")) {
1251            dataSelectId = mapperClassName + "." + dataSelectId;
1252        }
1253
1254        try (SqlSession sqlSession = sqlSessionFactory.openSession(executorType, false)) {
1255            if (page.getTotalRow() < 0) {
1256                if (!countSelectId.contains(".")) {
1257                    countSelectId = mapperClassName + "." + countSelectId;
1258                }
1259                Number number = sqlSession.selectOne(countSelectId, preparedParams);
1260                page.setTotalRow(number == null ? Page.INIT_VALUE : number.longValue());
1261            }
1262
1263            if (page.hasRecords()) {
1264                List<E> entities = sqlSession.selectList(dataSelectId, preparedParams);
1265                page.setRecords(entities);
1266            }
1267        }
1268        return page;
1269    }
1270
1271}