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