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}