
com.mybatisflex.core.BaseMapper Maven / Gradle / Ivy
/*
* Copyright (c) 2022-2025, Mybatis-Flex ([email protected]).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.core;
import com.mybatisflex.core.constant.FuncName;
import com.mybatisflex.core.exception.FlexAssert;
import com.mybatisflex.core.field.FieldQueryBuilder;
import com.mybatisflex.core.mybatis.MappedStatementTypes;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.provider.EntitySqlProvider;
import com.mybatisflex.core.query.CPI;
import com.mybatisflex.core.query.FunctionQueryColumn;
import com.mybatisflex.core.query.Join;
import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.Row;
import com.mybatisflex.core.table.TableInfo;
import com.mybatisflex.core.table.TableInfoFactory;
import com.mybatisflex.core.util.*;
import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider;
import org.apache.ibatis.builder.annotation.ProviderContext;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import static com.mybatisflex.core.query.QueryMethods.count;
/**
* 通用 Mapper 接口。
*
* @param 实体类类型
* @author 开源海哥
* @author 庄佳彬
* @author 闵柳华
* @author 王帅
* @author yangs
* @author lhzsdnu
* @author 王超
*/
@SuppressWarnings({"varargs", "unchecked", "unused"})
public interface BaseMapper {
/**
* 默认批量处理切片数量。
*/
int DEFAULT_BATCH_SIZE = 1000;
// === 增(insert) ===
/**
* 插入实体类数据,不忽略 {@code null} 值。
*
* @param entity 实体类
* @return 受影响的行数
*/
default int insert(T entity) {
return insert(entity, false);
}
/**
* 插入实体类数据,但是忽略 {@code null} 的数据,只对有值的内容进行插入。
* 这样的好处是数据库已经配置了一些默认值,这些默认值才会生效。
*
* @param entity 实体类
* @return 受影响的行数
*/
default int insertSelective(T entity) {
return insert(entity, true);
}
/**
* 插入实体类数据。
*
* @param entity 实体类
* @param ignoreNulls 是否忽略 {@code null} 值
* @return 受影响的行数
* @see com.mybatisflex.core.provider.EntitySqlProvider#insert(Map, ProviderContext)
*/
@InsertProvider(type = EntitySqlProvider.class, method = "insert")
int insert(@Param(FlexConsts.ENTITY) T entity, @Param(FlexConsts.IGNORE_NULLS) boolean ignoreNulls);
/**
* 插入带有主键的实体类,不忽略 {@code null} 值。
*
* @param entity 实体类
* @return 受影响的行数
*/
default int insertWithPk(T entity) {
return insertWithPk(entity, false);
}
/**
* 插入带有主键的实体类,忽略 {@code null} 值。
*
* @param entity 实体类
* @return 受影响的行数
*/
default int insertSelectiveWithPk(T entity) {
return insertWithPk(entity, true);
}
/**
* 带有主键的插入,此时实体类不会经过主键生成器生成主键。
*
* @param entity 带有主键的实体类
* @param ignoreNulls 是否忽略 {@code null} 值
* @return 受影响的行数
* @see com.mybatisflex.core.provider.EntitySqlProvider#insertWithPk(Map, ProviderContext)
*/
@InsertProvider(type = EntitySqlProvider.class, method = "insertWithPk")
int insertWithPk(@Param(FlexConsts.ENTITY) T entity, @Param(FlexConsts.IGNORE_NULLS) boolean ignoreNulls);
/**
* 批量插入实体类数据,只会根据第一条数据来构建插入的字段内容。
*
* @param entities 插入的数据列表
* @return 受影响的行数
* @see com.mybatisflex.core.provider.EntitySqlProvider#insertBatch(Map, ProviderContext)
* @see com.mybatisflex.core.FlexConsts#METHOD_INSERT_BATCH
*/
@InsertProvider(type = EntitySqlProvider.class, method = FlexConsts.METHOD_INSERT_BATCH)
int insertBatch(@Param(FlexConsts.ENTITIES) Collection entities);
/**
* 批量插入实体类数据,按 size 切分。
*
* @param entities 插入的数据列表
* @param size 切分大小
* @return 受影响的行数
*/
default int insertBatch(Collection entities, int size) {
// 让 insertBatch(List entities, int size) 和 insertBatch(List entities) 保持一样的验证行为
// https://gitee.com/mybatis-flex/mybatis-flex/issues/I9EGWA
FlexAssert.notEmpty(entities, "entities");
if (size <= 0) {
size = DEFAULT_BATCH_SIZE;
}
List entityList = entities instanceof List ? (List) entities : new ArrayList<>(entities);
int sum = 0;
int entitiesSize = entities.size();
int maxIndex = entitiesSize / size + (entitiesSize % size == 0 ? 0 : 1);
for (int i = 0; i < maxIndex; i++) {
List list = entityList.subList(i * size, Math.min(i * size + size, entitiesSize));
sum += insertBatch(list);
}
return sum;
}
/**
* 批量插入实体类数据,并自动忽略 null 值
*
* @param entities 插入的数据列表
* @return 受影响的行数
*/
default int insertBatchSelective(Collection entities) {
return insertBatchSelective(entities, DEFAULT_BATCH_SIZE);
}
/**
* 批量插入实体类数据,按 size 切分,并自动忽略 null 值
*
* @param entities 插入的数据列表
* @param size 切分大小
* @return 受影响的行数
*/
@SuppressWarnings("rawtypes")
default int insertBatchSelective(Collection entities, int size) {
FlexAssert.notEmpty(entities, "entities");
if (size <= 0) {
size = DEFAULT_BATCH_SIZE;
}
Class aClass = ClassUtil.getUsefulClass(this.getClass());
int[] batchResults = Db.executeBatch(entities, size, aClass, (BiConsumer) BaseMapper::insertSelective);
int result = 0;
for (int anInt : batchResults) {
if (anInt > 0) result += anInt;
}
return result;
}
/**
* 插入或者更新,若主键有值,则更新,若没有主键值,则插入,插入或者更新都不会忽略 {@code null} 值。
*
* @param entity 实体类
* @return 受影响的行数
*/
default int insertOrUpdate(T entity) {
return insertOrUpdate(entity, false);
}
/**
* 插入或者更新,若主键有值,则更新,若没有主键值,则插入,插入或者更新都会忽略 {@code null} 值。
*
* @param entity 实体类
* @return 受影响的行数
*/
default int insertOrUpdateSelective(T entity) {
return insertOrUpdate(entity, true);
}
/**
* 插入或者更新,若主键有值,则更新,若没有主键值,则插入。
*
* @param entity 实体类
* @param ignoreNulls 是否忽略 {@code null} 值
* @return 受影响的行数
*/
default int insertOrUpdate(T entity, boolean ignoreNulls) {
TableInfo tableInfo = TableInfoFactory.ofEntityClass(entity.getClass());
Object[] pkArgs = tableInfo.buildPkSqlArgs(entity);
if (pkArgs.length == 0 || pkArgs[0] == null || (pkArgs[0] instanceof String && StringUtil.noText((String) pkArgs[0]))) {
return insert(entity, ignoreNulls);
} else {
return update(entity, ignoreNulls);
}
}
// === 删(delete) ===
/**
* 根据实体主键来删除数据。
*
* @param entity 实体对象,必须包含有主键
* @return 受影响的行数
*/
default int delete(T entity) {
FlexAssert.notNull(entity, "entity can not be null");
TableInfo tableInfo = TableInfoFactory.ofEntityClass(entity.getClass());
Object[] pkArgs = tableInfo.buildPkSqlArgs(entity);
return deleteById(pkArgs);
}
/**
* 根据主键删除数据。如果是多个主键的情况下,需要传入数组,例如:{@code new Integer[]{100,101}}。
*
* @param id 主键数据
* @return 受影响的行数
* @see com.mybatisflex.core.provider.EntitySqlProvider#deleteById(Map, ProviderContext)
*/
@DeleteProvider(type = EntitySqlProvider.class, method = "deleteById")
int deleteById(@Param(FlexConsts.PRIMARY_VALUE) Serializable id);
/**
* 根据多个主键批量删除数据。
*
* @param ids 主键列表
* @return 受影响的行数
* @see com.mybatisflex.core.provider.EntitySqlProvider#deleteBatchByIds(Map, ProviderContext)
*/
@DeleteProvider(type = EntitySqlProvider.class, method = "deleteBatchByIds")
int deleteBatchByIds(@Param(FlexConsts.PRIMARY_VALUE) Collection extends Serializable> ids);
/**
* 根据多个主键批量删除数据。
*
* @param ids 主键列表
* @param size 切分大小
* @return 受影响的行数
* @see com.mybatisflex.core.provider.EntitySqlProvider#deleteBatchByIds(Map, ProviderContext)
*/
default int deleteBatchByIds(Collection extends Serializable> ids, int size) {
if (size <= 0) {
size = DEFAULT_BATCH_SIZE;
}
int sum = 0;
int entitiesSize = ids.size();
int maxIndex = entitiesSize / size + (entitiesSize % size == 0 ? 0 : 1);
List extends Serializable> idList = ids instanceof List ? (List extends Serializable>) ids : new ArrayList<>(ids);
for (int i = 0; i < maxIndex; i++) {
List extends Serializable> list = idList.subList(i * size, Math.min(i * size + size, entitiesSize));
sum += deleteBatchByIds(list);
}
return sum;
}
/**
* 根据 Map 构建的条件来删除数据。
*
* @param whereConditions 条件
* @return 受影响的行数
*/
default int deleteByMap(Map whereConditions) {
FlexAssert.notEmpty(whereConditions, "whereConditions");
return deleteByQuery(QueryWrapper.create().where(whereConditions));
}
/**
* 根据查询条件来删除数据。
*
* @param whereConditions 条件
* @return 受影响的行数
*/
default int deleteByCondition(QueryCondition whereConditions) {
FlexAssert.notNull(whereConditions, "whereConditions");
return deleteByQuery(QueryWrapper.create().where(whereConditions));
}
/**
* 根据查询条件来删除数据。
*
* @param queryWrapper 条件
* @return 受影响的行数
* @see com.mybatisflex.core.provider.EntitySqlProvider#deleteByQuery(Map, ProviderContext)
*/
@DeleteProvider(type = EntitySqlProvider.class, method = "deleteByQuery")
int deleteByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
// === 改(update) ===
/**
* 根据主键来更新数据,若实体类属性数据为 {@code null},该属性不会更新到数据库。
*
* @param entity 数据内容,必须包含有主键
* @return 受影响的行数
*/
default int update(T entity) {
return update(entity, true);
}
/**
* 根据主键来更新数据到数据库。
*
* @param entity 数据内容,必须包含有主键
* @param ignoreNulls 是否忽略空内容字段
* @return 受影响的行数
* @see com.mybatisflex.core.provider.EntitySqlProvider#update(Map, ProviderContext)
*/
@UpdateProvider(type = EntitySqlProvider.class, method = "update")
int update(@Param(FlexConsts.ENTITY) T entity, @Param(FlexConsts.IGNORE_NULLS) boolean ignoreNulls);
/**
* 根据 Map 构建的条件来更新数据。
*
* @param entity 实体类
* @param whereConditions 条件
* @return 受影响的行数
*/
default int updateByMap(T entity, Map whereConditions) {
FlexAssert.notEmpty(whereConditions, "whereConditions");
return updateByQuery(entity, QueryWrapper.create().where(whereConditions));
}
/**
* 根据 Map 构建的条件来更新数据。
*
* @param entity 实体类
* @param ignoreNulls 是否忽略 {@code null} 数据
* @param whereConditions 条件
* @return 受影响的行数
*/
default int updateByMap(T entity, boolean ignoreNulls, Map whereConditions) {
FlexAssert.notEmpty(whereConditions, "whereConditions");
return updateByQuery(entity, ignoreNulls, QueryWrapper.create().where(whereConditions));
}
/**
* 根据查询条件来更新数据。
*
* @param entity 实体类
* @param whereConditions 条件
* @return 受影响的行数
*/
default int updateByCondition(T entity, QueryCondition whereConditions) {
FlexAssert.notNull(whereConditions, "whereConditions");
return updateByQuery(entity, QueryWrapper.create().where(whereConditions));
}
/**
* 根据查询条件来更新数据。
*
* @param entity 实体类
* @param ignoreNulls 是否忽略 {@code null} 数据
* @param whereConditions 条件
* @return 受影响的行数
*/
default int updateByCondition(T entity, boolean ignoreNulls, QueryCondition whereConditions) {
FlexAssert.notNull(whereConditions, "whereConditions");
return updateByQuery(entity, ignoreNulls, QueryWrapper.create().where(whereConditions));
}
/**
* 根据查询条件来更新数据。
*
* @param entity 实体类
* @param queryWrapper 条件
* @return 受影响的行数
*/
default int updateByQuery(T entity, QueryWrapper queryWrapper) {
return updateByQuery(entity, true, queryWrapper);
}
/**
* 根据查询条件来更新数据。
*
* @param entity 实体类
* @param ignoreNulls 是否忽略空值
* @param queryWrapper 条件
* @return 受影响的行数
* @see com.mybatisflex.core.provider.EntitySqlProvider#updateByQuery(Map, ProviderContext)
*/
@UpdateProvider(type = EntitySqlProvider.class, method = "updateByQuery")
int updateByQuery(@Param(FlexConsts.ENTITY) T entity, @Param(FlexConsts.IGNORE_NULLS) boolean ignoreNulls, @Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
// === 查(select) ===
/**
* 根据实体主键查询数据。
*
* @param entity 实体对象,必须包含有主键
* @return 实体类数据
*/
default T selectOneByEntityId(T entity) {
FlexAssert.notNull(entity, "entity can not be null");
TableInfo tableInfo = TableInfoFactory.ofEntityClass(entity.getClass());
Object[] pkArgs = tableInfo.buildPkSqlArgs(entity);
return selectOneById(pkArgs);
}
/**
* 根据主键查询数据。
*
* @param id 主键
* @return 实体类数据
* @see com.mybatisflex.core.provider.EntitySqlProvider#selectOneById(Map, ProviderContext)
*/
@SelectProvider(type = EntitySqlProvider.class, method = "selectOneById")
T selectOneById(@Param(FlexConsts.PRIMARY_VALUE) Serializable id);
/**
* 根据 Map 构建的条件来查询数据。
*
* @param whereConditions 条件
* @return 实体类数据
*/
default T selectOneByMap(Map whereConditions) {
FlexAssert.notEmpty(whereConditions, "whereConditions");
return selectOneByQuery(QueryWrapper.create().where(whereConditions));
}
/**
* 根据查询条件查询数据。
*
* @param whereConditions 条件
* @return 实体类数据
*/
default T selectOneByCondition(QueryCondition whereConditions) {
FlexAssert.notNull(whereConditions, "whereConditions");
return selectOneByQuery(QueryWrapper.create().where(whereConditions));
}
/**
* 根据查询条件来查询 1 条数据。
*
* @param queryWrapper 条件
* @return 实体类数据
*/
default T selectOneByQuery(QueryWrapper queryWrapper) {
List joins = CPI.getJoins(queryWrapper);
if (CollectionUtil.isNotEmpty(joins)) {
return MapperUtil.getSelectOneResult(selectListByQuery(queryWrapper));
}
Long limitRows = CPI.getLimitRows(queryWrapper);
try {
queryWrapper.limit(1);
return MapperUtil.getSelectOneResult(selectListByQuery(queryWrapper));
} finally {
CPI.setLimitRows(queryWrapper, limitRows);
}
}
/**
* 根据查询条件来查询 1 条数据。
*
* @param queryWrapper 条件
* @param asType 接收数据类型
* @return 实体类数据
*/
default R selectOneByQueryAs(QueryWrapper queryWrapper, Class asType) {
List joins = CPI.getJoins(queryWrapper);
if (CollectionUtil.isNotEmpty(joins)) {
return MapperUtil.getSelectOneResult(selectListByQueryAs(queryWrapper, asType));
}
Long limitRows = CPI.getLimitRows(queryWrapper);
try {
queryWrapper.limit(1);
return MapperUtil.getSelectOneResult(selectListByQueryAs(queryWrapper, asType));
} finally {
CPI.setLimitRows(queryWrapper, limitRows);
}
}
/**
* 根据 Map 构建的条件来查询 1 条数据。
*
* @param whereConditions 条件
* @return 实体类数据
*/
default T selectOneWithRelationsByMap(Map whereConditions) {
FlexAssert.notEmpty(whereConditions, "whereConditions");
return selectOneWithRelationsByQuery(QueryWrapper.create().where(whereConditions));
}
/**
* 根据查询条件查询 1 条数据。
*
* @param whereConditions 条件
* @return 实体类数据
*/
default T selectOneWithRelationsByCondition(QueryCondition whereConditions) {
FlexAssert.notNull(whereConditions, "whereConditions");
return selectOneWithRelationsByQuery(QueryWrapper.create().where(whereConditions));
}
/**
* 根据查询条件来查询 1 条数据。
*
* @param queryWrapper 条件
* @return 实体类数据
*/
default T selectOneWithRelationsByQuery(QueryWrapper queryWrapper) {
List joins = CPI.getJoins(queryWrapper);
if (CollectionUtil.isNotEmpty(joins)) {
return MapperUtil.queryRelations(this, MapperUtil.getSelectOneResult(selectListByQuery(queryWrapper)));
}
Long limitRows = CPI.getLimitRows(queryWrapper);
try {
queryWrapper.limit(1);
return MapperUtil.queryRelations(this, MapperUtil.getSelectOneResult(selectListByQuery(queryWrapper)));
} finally {
CPI.setLimitRows(queryWrapper, limitRows);
}
}
/**
* 根据主表主键来查询 1 条数据。
*
* @param id 主表主键
* @return 实体类数据
*/
default T selectOneWithRelationsById(Serializable id) {
return MapperUtil.queryRelations(this, selectOneById(id));
}
/**
* 根据主表主键来查询 1 条数据。
*
* @param id 表主键
* @param asType 接收数据类型
* @return 实体类数据
*/
default R selectOneWithRelationsByIdAs(Serializable id, Class asType) {
R result;
try {
MappedStatementTypes.setCurrentType(asType);
result = (R) selectOneById(id);
} finally {
MappedStatementTypes.clear();
}
return MapperUtil.queryRelations(this, result);
}
/**
* 根据查询条件来查询 1 条数据。
*
* @param queryWrapper 条件
* @param asType 接收数据类型
* @return 实体类数据
*/
default R selectOneWithRelationsByQueryAs(QueryWrapper queryWrapper, Class asType) {
List joins = CPI.getJoins(queryWrapper);
if (CollectionUtil.isNotEmpty(joins)) {
return MapperUtil.queryRelations(this, MapperUtil.getSelectOneResult(selectListByQueryAs(queryWrapper, asType)));
}
Long limitRows = CPI.getLimitRows(queryWrapper);
try {
queryWrapper.limit(1);
return MapperUtil.queryRelations(this, MapperUtil.getSelectOneResult(selectListByQueryAs(queryWrapper, asType)));
} finally {
CPI.setLimitRows(queryWrapper, limitRows);
}
}
/**
* 根据多个主键来查询多条数据。
*
* @param ids 主键列表
* @return 数据列表
* @see com.mybatisflex.core.provider.EntitySqlProvider#selectListByIds(Map, ProviderContext)
*/
@SelectProvider(type = EntitySqlProvider.class, method = "selectListByIds")
List selectListByIds(@Param(FlexConsts.PRIMARY_VALUE) Collection extends Serializable> ids);
/**
* 根据 Map 来构建查询条件,查询多条数据。
*
* @param whereConditions 条件
* @return 数据列表
*/
default List selectListByMap(Map whereConditions) {
FlexAssert.notEmpty(whereConditions, "whereConditions");
return selectListByQuery(QueryWrapper.create().where(whereConditions));
}
/**
* 根据 Map 来构建查询条件,查询多条数据。
*
* @param whereConditions 条件
* @param count 数据量
* @return 数据列表
*/
default List selectListByMap(Map whereConditions, Long count) {
FlexAssert.notEmpty(whereConditions, "whereConditions");
return selectListByQuery(QueryWrapper.create().where(whereConditions).limit(count));
}
/**
* 根据查询条件查询多条数据。
*
* @param whereConditions 条件
* @return 数据列表
*/
default List selectListByCondition(QueryCondition whereConditions) {
FlexAssert.notNull(whereConditions, "whereConditions");
return selectListByQuery(QueryWrapper.create().where(whereConditions));
}
/**
* 根据查询条件查询多条数据。
*
* @param whereConditions 条件
* @param count 数据量
* @return 数据列表
*/
default List selectListByCondition(QueryCondition whereConditions, Long count) {
FlexAssert.notNull(whereConditions, "whereConditions");
return selectListByQuery(QueryWrapper.create().where(whereConditions).limit(count));
}
/**
* 根据查询条件查询数据列表。
*
* @param queryWrapper 条件
* @return 数据列表
* @see com.mybatisflex.core.provider.EntitySqlProvider#selectListByQuery(Map, ProviderContext)
*/
@SelectProvider(type = EntitySqlProvider.class, method = "selectListByQuery")
List selectListByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
/**
* 根据查询条件查询数据列表。
*
* @param queryWrapper 条件
* @param consumers 字段查询
* @return 数据列表
*/
default List selectListByQuery(QueryWrapper queryWrapper, Consumer>... consumers) {
List list = selectListByQuery(queryWrapper);
if (list == null || list.isEmpty()) {
return Collections.emptyList();
}
MapperUtil.queryFields(this, list, consumers);
return list;
}
/**
* 根据查询条件查询游标数据,该方法必须在事务中才能正常使用,非事务下无法获取数据。
*
* @param queryWrapper 条件
* @return 游标数据
*/
@SelectProvider(type = EntitySqlProvider.class, method = "selectListByQuery")
Cursor selectCursorByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
/**
* 根据查询条件查询游标数据,要求返回的数据为 asType 类型。该方法必须在事务中才能正常使用,非事务下无法获取数据。
*
* @param queryWrapper 条件
* @param asType 接收的数据类型
* @return 游标数据
*/
default Cursor selectCursorByQueryAs(QueryWrapper queryWrapper, Class asType) {
try {
MappedStatementTypes.setCurrentType(asType);
return (Cursor) selectCursorByQuery(queryWrapper);
} finally {
MappedStatementTypes.clear();
}
}
/**
* 根据查询条件查询 Row 数据。
*
* @param queryWrapper 条件
* @return 行数据
*/
@SelectProvider(type = EntitySqlProvider.class, method = "selectListByQuery")
List selectRowsByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
/**
* 根据查询条件查询数据列表,要求返回的数据为 asType。这种场景一般用在 left join 时,
* 有多出了实体类本身的字段内容,可以转换为 dto、vo 等场景。
*
* @param queryWrapper 条件
* @param asType 接收数据类型
* @return 数据列表
*/
default List selectListByQueryAs(QueryWrapper queryWrapper, Class asType) {
if (Number.class.isAssignableFrom(asType)
|| String.class == asType) {
return selectObjectListByQueryAs(queryWrapper, asType);
}
if (Map.class.isAssignableFrom(asType)) {
return (List) selectRowsByQuery(queryWrapper);
}
try {
MappedStatementTypes.setCurrentType(asType);
return (List) selectListByQuery(queryWrapper);
} finally {
MappedStatementTypes.clear();
}
}
/**
* 根据查询条件查询数据列表,要求返回的数据为 asType 类型。
*
* @param queryWrapper 条件
* @param asType 接收的数据类型
* @param consumers 字段查询
* @return 数据列表
*/
default List selectListByQueryAs(QueryWrapper queryWrapper, Class asType, Consumer>... consumers) {
List list = selectListByQueryAs(queryWrapper, asType);
if (list == null || list.isEmpty()) {
return Collections.emptyList();
} else {
MapperUtil.queryFields(this, list, consumers);
return list;
}
}
/**
* 查询实体类及其 Relation 注解字段。
*
* @param queryWrapper 条件
*/
default List selectListWithRelationsByQuery(QueryWrapper queryWrapper) {
return MapperUtil.queryRelations(this, selectListByQuery(queryWrapper));
}
/**
* 查询实体类及其 Relation 注解字段。
*
* @param queryWrapper 条件
* @param asType 要求返回的数据类型
* @return 数据列表
*/
default List selectListWithRelationsByQueryAs(QueryWrapper queryWrapper, Class asType) {
if (Number.class.isAssignableFrom(asType)
|| String.class == asType) {
return selectObjectListByQueryAs(queryWrapper, asType);
}
if (Map.class.isAssignableFrom(asType)) {
return (List) selectRowsByQuery(queryWrapper);
}
List result;
try {
MappedStatementTypes.setCurrentType(asType);
result = selectListByQuery(queryWrapper);
} finally {
MappedStatementTypes.clear();
}
return MapperUtil.queryRelations(this, (List) result);
}
/**
* 查询实体类及其 Relation 注解字段。
*
* @param queryWrapper 条件
* @param asType 返回的类型
* @param consumers 字段查询
* @return 数据列表
*/
default List selectListWithRelationsByQueryAs(QueryWrapper queryWrapper, Class asType, Consumer>... consumers) {
List list = selectListByQueryAs(queryWrapper, asType);
if (list == null || list.isEmpty()) {
return Collections.emptyList();
} else {
MapperUtil.queryRelations(this, list);
MapperUtil.queryFields(this, list, consumers);
return list;
}
}
/**
* 查询全部数据。
*
* @return 数据列表
*/
default List selectAll() {
return selectListByQuery(new QueryWrapper());
}
/**
* 查询全部数据,及其 Relation 字段内容。
*
* @return 数据列表
*/
default List selectAllWithRelations() {
return MapperUtil.queryRelations(this, selectListByQuery(new QueryWrapper()));
}
/**
* 查询第一列返回的数据,QueryWrapper 执行的结果应该只有 1 列,例如:
* {@code QueryWrapper.create().select(ACCOUNT.id).where(...);}
*
* @param queryWrapper 查询包装器
* @return 数据量
*/
default Object selectObjectByQuery(QueryWrapper queryWrapper) {
return MapperUtil.getSelectOneResult(selectObjectListByQuery(queryWrapper));
}
/**
* 查询第一列返回的数据,QueryWrapper 执行的结果应该只有 1 列,例如:
* {@code QueryWrapper.create().select(ACCOUNT.id).where(...);}
*
* @param queryWrapper 查询包装器
* @param asType 转换成的数据类型
* @return 数据量
*/
default R selectObjectByQueryAs(QueryWrapper queryWrapper, Class asType) {
return MapperUtil.getSelectOneResult(selectObjectListByQueryAs(queryWrapper, asType));
}
/**
* 查询第一列返回的数据集合,QueryWrapper 执行的结果应该只有 1 列,例如:
* {@code QueryWrapper.create().select(ACCOUNT.id).where(...);}
*
* @param queryWrapper 查询包装器
* @return 数据列表
* @see EntitySqlProvider#selectObjectByQuery(Map, ProviderContext)
*/
@SelectProvider(type = EntitySqlProvider.class, method = "selectObjectByQuery")
List