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