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