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