mirror of
https://gitee.com/mybatis-flex/mybatis-flex.git
synced 2025-12-06 16:48:24 +08:00
优化 BaseMapper.selectListByQueryAs() 方法
This commit is contained in:
parent
0f9db633e2
commit
e12d92f17c
@ -358,13 +358,8 @@ public interface BaseMapper<T> {
|
||||
* @return 数据内容
|
||||
*/
|
||||
default <R> R selectOneByQueryAs(QueryWrapper queryWrapper, Class<R> asType) {
|
||||
try {
|
||||
MappedStatementTypes.setCurrentType(asType);
|
||||
List<R> entities = selectListByQueryAs(queryWrapper.limit(1), asType);
|
||||
return (entities == null || entities.isEmpty()) ? null : entities.get(0);
|
||||
} finally {
|
||||
MappedStatementTypes.clear();
|
||||
}
|
||||
List<R> entities = selectListByQueryAs(queryWrapper.limit(1), asType);
|
||||
return (entities == null || entities.isEmpty()) ? null : entities.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -434,7 +429,7 @@ public interface BaseMapper<T> {
|
||||
List<T> selectListByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper);
|
||||
|
||||
|
||||
default List<T> selectListByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper
|
||||
default List<T> selectListByQuery(QueryWrapper queryWrapper
|
||||
, Consumer<FieldQueryBuilder<T>>... consumers) {
|
||||
|
||||
List<T> list = selectListByQuery(queryWrapper);
|
||||
@ -442,41 +437,7 @@ public interface BaseMapper<T> {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
list.forEach(entity -> {
|
||||
for (Consumer<FieldQueryBuilder<T>> consumer : consumers) {
|
||||
FieldQueryBuilder<T> fieldQueryBuilder = new FieldQueryBuilder<>(entity);
|
||||
consumer.accept(fieldQueryBuilder);
|
||||
FieldQuery fieldQuery = fieldQueryBuilder.build();
|
||||
QueryWrapper childQuery = fieldQuery.getQueryWrapper();
|
||||
|
||||
FieldWrapper fieldWrapper = FieldWrapper.of(entity.getClass(), fieldQuery.getField());
|
||||
if (fieldWrapper == null) {
|
||||
throw new IllegalStateException("Can not find field \"" + fieldQuery.getField() + "\" in class: " + entity.getClass());
|
||||
}
|
||||
|
||||
Class<?> fieldType = fieldWrapper.getFieldType();
|
||||
Class<?> mappingType = fieldWrapper.getMappingType();
|
||||
|
||||
Object value;
|
||||
try {
|
||||
MappedStatementTypes.setCurrentType(mappingType);
|
||||
if (fieldType.isAssignableFrom(List.class)) {
|
||||
value = selectListByQueryAs(childQuery, mappingType);
|
||||
} else if (fieldType.isAssignableFrom(Set.class)) {
|
||||
value = selectListByQueryAs(childQuery, mappingType);
|
||||
value = new HashSet<>((Collection<?>) value);
|
||||
} else if (fieldType.isArray()) {
|
||||
value = selectListByQueryAs(childQuery, mappingType);
|
||||
value = ((List<?>) value).toArray();
|
||||
} else {
|
||||
value = selectOneByQueryAs(childQuery, mappingType);
|
||||
}
|
||||
} finally {
|
||||
MappedStatementTypes.clear();
|
||||
}
|
||||
fieldWrapper.set(value, entity);
|
||||
}
|
||||
});
|
||||
__queryFields(list, consumers);
|
||||
|
||||
return list;
|
||||
}
|
||||
@ -490,62 +451,25 @@ public interface BaseMapper<T> {
|
||||
* @param asType 接收数据类型
|
||||
* @return 数据列表
|
||||
*/
|
||||
@SelectProvider(type = EntitySqlProvider.class, method = "selectListByQuery")
|
||||
<R> List<R> selectListByQueryAs(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper, Class<R> asType);
|
||||
|
||||
|
||||
default <R> List<R> selectListByQueryAs(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper, Class<R> asType
|
||||
, Consumer<FieldQueryBuilder<R>>... consumers) {
|
||||
List<R> list;
|
||||
default <R> List<R> selectListByQueryAs(QueryWrapper queryWrapper, Class<R> asType) {
|
||||
try {
|
||||
MappedStatementTypes.setCurrentType(asType);
|
||||
list = selectListByQueryAs(queryWrapper, asType);
|
||||
return (List<R>) selectListByQuery(queryWrapper);
|
||||
} finally {
|
||||
MappedStatementTypes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
default <R> List<R> selectListByQueryAs(QueryWrapper queryWrapper, Class<R> asType
|
||||
, Consumer<FieldQueryBuilder<R>>... consumers) {
|
||||
List<R> list = selectListByQueryAs(queryWrapper, asType);
|
||||
if (list == null || list.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
__queryFields(list, consumers);
|
||||
return list;
|
||||
}
|
||||
|
||||
list.forEach(entity -> {
|
||||
for (Consumer<FieldQueryBuilder<R>> consumer : consumers) {
|
||||
FieldQueryBuilder<R> fieldQueryBuilder = new FieldQueryBuilder<>(entity);
|
||||
consumer.accept(fieldQueryBuilder);
|
||||
FieldQuery fieldQuery = fieldQueryBuilder.build();
|
||||
QueryWrapper childQuery = fieldQuery.getQueryWrapper();
|
||||
|
||||
FieldWrapper fieldWrapper = FieldWrapper.of(entity.getClass(), fieldQuery.getField());
|
||||
|
||||
if (fieldWrapper == null) {
|
||||
throw new IllegalStateException("Can not find field \"" + fieldQuery.getField() + "\" in class: " + entity.getClass());
|
||||
}
|
||||
|
||||
Class<?> fieldType = fieldWrapper.getFieldType();
|
||||
Class<?> mappingType = fieldWrapper.getMappingType();
|
||||
|
||||
Object value;
|
||||
try {
|
||||
MappedStatementTypes.setCurrentType(mappingType);
|
||||
if (fieldType.isAssignableFrom(List.class)) {
|
||||
value = selectListByQueryAs(childQuery, mappingType);
|
||||
} else if (fieldType.isAssignableFrom(Set.class)) {
|
||||
value = selectListByQueryAs(childQuery, mappingType);
|
||||
value = new HashSet<>((Collection<?>) value);
|
||||
} else if (fieldType.isArray()) {
|
||||
value = selectListByQueryAs(childQuery, mappingType);
|
||||
value = ((List<?>) value).toArray();
|
||||
} else {
|
||||
value = selectOneByQueryAs(childQuery, mappingType);
|
||||
}
|
||||
} finally {
|
||||
MappedStatementTypes.clear();
|
||||
}
|
||||
fieldWrapper.set(value, entity);
|
||||
}
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
@ -786,19 +710,48 @@ public interface BaseMapper<T> {
|
||||
queryWrapper.limit(offset, page.getPageSize());
|
||||
|
||||
if (asType != null) {
|
||||
try {
|
||||
// 调用内部方法,不走代理,需要主动设置 MappedStatementType
|
||||
// fixed https://gitee.com/mybatis-flex/mybatis-flex/issues/I73BP6
|
||||
MappedStatementTypes.setCurrentType(asType);
|
||||
List<R> records = selectListByQueryAs(queryWrapper, asType, consumers);
|
||||
page.setRecords(records);
|
||||
} finally {
|
||||
MappedStatementTypes.clear();
|
||||
}
|
||||
List<R> records = selectListByQueryAs(queryWrapper, asType);
|
||||
__queryFields(records, consumers);
|
||||
page.setRecords(records);
|
||||
} else {
|
||||
List<R> records = (List<R>) selectListByQuery(queryWrapper);
|
||||
__queryFields(records, consumers);
|
||||
page.setRecords(records);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
|
||||
default <R> void __queryFields(List<R> list, Consumer<FieldQueryBuilder<R>>[] consumers) {
|
||||
if (CollectionUtil.isEmpty(list) || ArrayUtil.isEmpty(consumers) || consumers[0] == null) {
|
||||
return;
|
||||
}
|
||||
list.forEach(entity -> {
|
||||
for (Consumer<FieldQueryBuilder<R>> consumer : consumers) {
|
||||
FieldQueryBuilder<R> fieldQueryBuilder = new FieldQueryBuilder<>(entity);
|
||||
consumer.accept(fieldQueryBuilder);
|
||||
FieldQuery fieldQuery = fieldQueryBuilder.build();
|
||||
QueryWrapper childQuery = fieldQuery.getQueryWrapper();
|
||||
|
||||
FieldWrapper fieldWrapper = FieldWrapper.of(entity.getClass(), fieldQuery.getField());
|
||||
|
||||
Class<?> fieldType = fieldWrapper.getFieldType();
|
||||
Class<?> mappingType = fieldWrapper.getMappingType();
|
||||
|
||||
Object value;
|
||||
if (fieldType.isAssignableFrom(List.class)) {
|
||||
value = selectListByQueryAs(childQuery, mappingType);
|
||||
} else if (fieldType.isAssignableFrom(Set.class)) {
|
||||
value = selectListByQueryAs(childQuery, mappingType);
|
||||
value = new HashSet<>((Collection<?>) value);
|
||||
} else if (fieldType.isArray()) {
|
||||
value = selectListByQueryAs(childQuery, mappingType);
|
||||
value = ((List<?>) value).toArray();
|
||||
} else {
|
||||
value = selectOneByQueryAs(childQuery, mappingType);
|
||||
}
|
||||
fieldWrapper.set(value, entity);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,7 +41,6 @@ public class FlexConsts {
|
||||
public static final String IGNORE_NULLS = "$$ignoreNulls";
|
||||
|
||||
public static final String METHOD_INSERT_BATCH = "insertBatch";
|
||||
public static final String METHOD_SELECT_LIST_BY_QUERY_AS = "selectListByQueryAs";
|
||||
|
||||
/**
|
||||
* 当 entity 使用逻辑删除时,0 为 entity 的正常状态
|
||||
|
||||
@ -133,9 +133,9 @@ public class FlexConfiguration extends Configuration {
|
||||
public MappedStatement getMappedStatement(String id) {
|
||||
MappedStatement ms = super.getMappedStatement(id);
|
||||
|
||||
//动态 resultsMap
|
||||
if (id.endsWith(FlexConsts.METHOD_SELECT_LIST_BY_QUERY_AS)) {
|
||||
Class<?> asType = MappedStatementTypes.getCurrentType();
|
||||
//动态 resultsMap,方法名称为:selectListByQuery
|
||||
Class<?> asType = MappedStatementTypes.getCurrentType();
|
||||
if (asType != null) {
|
||||
return MapUtil.computeIfAbsent(dynamicMappedStatementCache, asType,
|
||||
aClass -> replaceResultMap(ms, TableInfoFactory.ofEntityClass(asType))
|
||||
);
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
package com.mybatisflex.core.mybatis;
|
||||
|
||||
import com.mybatisflex.annotation.UseDataSource;
|
||||
import com.mybatisflex.core.FlexConsts;
|
||||
import com.mybatisflex.core.FlexGlobalConfig;
|
||||
import com.mybatisflex.core.datasource.DataSourceKey;
|
||||
import com.mybatisflex.core.datasource.FlexDataSource;
|
||||
@ -46,11 +45,7 @@ public class MapperInvocationHandler implements InvocationHandler {
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
boolean clearDsKey = false;
|
||||
boolean clearDbType = false;
|
||||
boolean isSelectListByQueryAsMethod = FlexConsts.METHOD_SELECT_LIST_BY_QUERY_AS.equals(method.getName());
|
||||
try {
|
||||
if (isSelectListByQueryAsMethod){
|
||||
MappedStatementTypes.setCurrentType((Class<?>) args[1]);
|
||||
}
|
||||
//获取用户动态指定,由用户指定数据源,则应该有用户清除
|
||||
String dataSourceKey = DataSourceKey.get();
|
||||
|
||||
@ -78,9 +73,6 @@ public class MapperInvocationHandler implements InvocationHandler {
|
||||
}
|
||||
return method.invoke(mapper, args);
|
||||
} finally {
|
||||
if (isSelectListByQueryAsMethod){
|
||||
MappedStatementTypes.clear();
|
||||
}
|
||||
if (clearDbType) {
|
||||
DialectFactory.clearHintDbType();
|
||||
}
|
||||
|
||||
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.mybatisflex.core.util;
|
||||
|
||||
import com.mybatisflex.core.exception.FlexExceptions;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
@ -26,7 +28,7 @@ public class FieldWrapper {
|
||||
|
||||
private Class<?> fieldType;
|
||||
private Class<?> mappingType;
|
||||
private Method method;
|
||||
private Method setterMethod;
|
||||
|
||||
public static FieldWrapper of(Class<?> clazz, String fieldName) {
|
||||
Map<String, FieldWrapper> wrapperMap = cache.get(clazz);
|
||||
@ -46,18 +48,22 @@ public class FieldWrapper {
|
||||
if (fieldWrapper == null) {
|
||||
Field findField = ClassUtil.getFirstField(clazz, field -> field.getName().equals(fieldName));
|
||||
if (findField == null) {
|
||||
return null;
|
||||
throw new IllegalStateException("Can not find field \"" + fieldName + "\" in class: " + clazz);
|
||||
}
|
||||
|
||||
fieldWrapper = new FieldWrapper();
|
||||
fieldWrapper.fieldType = findField.getType();
|
||||
fieldWrapper.mappingType = getFieldMappingType(findField);
|
||||
|
||||
Method setter = ClassUtil.getFirstMethod(clazz, method ->
|
||||
method.getParameterCount() == 1
|
||||
&& Modifier.isPublic(method.getModifiers())
|
||||
&& method.getName().equals("set" + StringUtil.firstCharToUpperCase(fieldName)));
|
||||
fieldWrapper.method = setter;
|
||||
|
||||
if (setter == null) {
|
||||
throw FlexExceptions.wrap("Can not find method \"set" + StringUtil.firstCharToUpperCase(fieldName) + "\" in class: " + clazz);
|
||||
}
|
||||
|
||||
fieldWrapper = new FieldWrapper();
|
||||
fieldWrapper.fieldType = findField.getType();
|
||||
fieldWrapper.mappingType = parseMappingType(findField);
|
||||
fieldWrapper.setterMethod = setter;
|
||||
|
||||
wrapperMap.put(fieldName, fieldWrapper);
|
||||
}
|
||||
@ -67,7 +73,7 @@ public class FieldWrapper {
|
||||
return fieldWrapper;
|
||||
}
|
||||
|
||||
private static Class<?> getFieldMappingType(Field field) {
|
||||
private static Class<?> parseMappingType(Field field) {
|
||||
Class<?> fieldType = field.getType();
|
||||
if (Collection.class.isAssignableFrom(fieldType)) {
|
||||
Type genericType = field.getGenericType();
|
||||
@ -87,7 +93,7 @@ public class FieldWrapper {
|
||||
|
||||
public void set(Object value, Object to) {
|
||||
try {
|
||||
method.invoke(to, value);
|
||||
setterMethod.invoke(to, value);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user