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