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