feat: 优化 ResultMap 构建,又双叒叕处理重名问题。

This commit is contained in:
Suomm 2024-01-21 19:38:38 +08:00
parent ab7e705b45
commit bef851d017
2 changed files with 97 additions and 31 deletions

View File

@ -15,7 +15,11 @@
*/ */
package com.mybatisflex.core.table; package com.mybatisflex.core.table;
import com.mybatisflex.annotation.*; import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.InsertListener;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.SetListener;
import com.mybatisflex.annotation.UpdateListener;
import com.mybatisflex.core.FlexConsts; import com.mybatisflex.core.FlexConsts;
import com.mybatisflex.core.FlexGlobalConfig; import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.constant.SqlConsts; import com.mybatisflex.core.constant.SqlConsts;
@ -25,12 +29,30 @@ import com.mybatisflex.core.exception.FlexExceptions;
import com.mybatisflex.core.exception.locale.LocalizedFormats; import com.mybatisflex.core.exception.locale.LocalizedFormats;
import com.mybatisflex.core.logicdelete.LogicDeleteManager; import com.mybatisflex.core.logicdelete.LogicDeleteManager;
import com.mybatisflex.core.mybatis.TypeHandlerObject; import com.mybatisflex.core.mybatis.TypeHandlerObject;
import com.mybatisflex.core.query.*; import com.mybatisflex.core.query.CPI;
import com.mybatisflex.core.query.Join;
import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryMethods;
import com.mybatisflex.core.query.QueryTable;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.query.SelectQueryColumn;
import com.mybatisflex.core.query.SelectQueryTable;
import com.mybatisflex.core.query.SqlOperators;
import com.mybatisflex.core.query.UnionWrapper;
import com.mybatisflex.core.row.Row; import com.mybatisflex.core.row.Row;
import com.mybatisflex.core.tenant.TenantManager; import com.mybatisflex.core.tenant.TenantManager;
import com.mybatisflex.core.update.RawValue; import com.mybatisflex.core.update.RawValue;
import com.mybatisflex.core.update.UpdateWrapper; import com.mybatisflex.core.update.UpdateWrapper;
import com.mybatisflex.core.util.*; import com.mybatisflex.core.util.ArrayUtil;
import com.mybatisflex.core.util.ClassUtil;
import com.mybatisflex.core.util.CollectionUtil;
import com.mybatisflex.core.util.ConvertUtil;
import com.mybatisflex.core.util.EnumWrapper;
import com.mybatisflex.core.util.FieldWrapper;
import com.mybatisflex.core.util.ObjectUtil;
import com.mybatisflex.core.util.SqlUtil;
import com.mybatisflex.core.util.StringUtil;
import org.apache.ibatis.mapping.ResultFlag; import org.apache.ibatis.mapping.ResultFlag;
import org.apache.ibatis.mapping.ResultMap; import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.ResultMapping; import org.apache.ibatis.mapping.ResultMapping;
@ -45,11 +67,25 @@ import java.lang.reflect.Field;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.*; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.StringJoiner;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.mybatisflex.core.constant.SqlConsts.*; import static com.mybatisflex.core.constant.SqlConsts.AND;
import static com.mybatisflex.core.constant.SqlConsts.EQUALS_PLACEHOLDER;
import static com.mybatisflex.core.constant.SqlConsts.IN;
public class TableInfo { public class TableInfo {
@ -989,10 +1025,20 @@ public class TableInfo {
public ResultMap buildResultMap(Configuration configuration) { public ResultMap buildResultMap(Configuration configuration) {
return doBuildResultMap(configuration, new HashSet<>(), false, getTableNameWithSchema()); // 所有的嵌套类对象引用
Stream<Class<?>> ct = collectionType == null ? Stream.empty() : collectionType.values().stream();
Stream<Class<?>> at = associationType == null ? Stream.empty() : associationType.values().stream();
// 预加载所有的列重复列去重
Set<String> existedColumns = Stream.concat(at, ct)
.map(TableInfoFactory::ofEntityClass)
.flatMap(e -> Arrays.stream(e.allColumns))
.collect(Collectors.toSet());
return doBuildResultMap(configuration, new HashSet<>(), existedColumns, false, getTableNameWithSchema());
} }
private ResultMap doBuildResultMap(Configuration configuration, Set<String> resultMapIds, boolean isNested, String nestedPrefix) { private ResultMap doBuildResultMap(Configuration configuration, Set<String> resultMapIds, Set<String> existedColumns, boolean isNested, String nestedPrefix) {
String resultMapId = isNested ? "nested-" + nestedPrefix + ":" + entityClass.getName() : entityClass.getName(); String resultMapId = isNested ? "nested-" + nestedPrefix + ":" + entityClass.getName() : entityClass.getName();
@ -1012,12 +1058,12 @@ public class TableInfo {
// <resultMap> 标签下的 <id> 标签映射 // <resultMap> 标签下的 <id> 标签映射
for (IdInfo idInfo : primaryKeyList) { for (IdInfo idInfo : primaryKeyList) {
doBuildColumnResultMapping(configuration, resultMappings, idInfo, CollectionUtil.newArrayList(ResultFlag.ID)); doBuildColumnResultMapping(configuration, resultMappings, existedColumns, idInfo, CollectionUtil.newArrayList(ResultFlag.ID), isNested);
} }
// <resultMap> 标签下的 <result> 标签映射 // <resultMap> 标签下的 <result> 标签映射
for (ColumnInfo columnInfo : columnInfoList) { for (ColumnInfo columnInfo : columnInfoList) {
doBuildColumnResultMapping(configuration, resultMappings, columnInfo, Collections.emptyList()); doBuildColumnResultMapping(configuration, resultMappings, existedColumns, columnInfo, Collections.emptyList(), isNested);
} }
// <resultMap> 标签下的 <association> 标签映射 // <resultMap> 标签下的 <association> 标签映射
@ -1026,7 +1072,7 @@ public class TableInfo {
// 获取嵌套类型的信息也就是 javaType 属性 // 获取嵌套类型的信息也就是 javaType 属性
TableInfo tableInfo = TableInfoFactory.ofEntityClass(fieldType); TableInfo tableInfo = TableInfoFactory.ofEntityClass(fieldType);
// 构建嵌套类型的 ResultMap 对象也就是 <association> 标签下的内容 // 构建嵌套类型的 ResultMap 对象也就是 <association> 标签下的内容
ResultMap nestedResultMap = tableInfo.doBuildResultMap(configuration, resultMapIds, true, nestedPrefix); ResultMap nestedResultMap = tableInfo.doBuildResultMap(configuration, resultMapIds, existedColumns, true, nestedPrefix);
if (nestedResultMap != null) { if (nestedResultMap != null) {
resultMappings.add(new ResultMapping.Builder(configuration, fieldName) resultMappings.add(new ResultMapping.Builder(configuration, fieldName)
.javaType(fieldType) .javaType(fieldType)
@ -1059,7 +1105,7 @@ public class TableInfo {
// 获取集合泛型类型的信息也就是 ofType 属性 // 获取集合泛型类型的信息也就是 ofType 属性
TableInfo tableInfo = TableInfoFactory.ofEntityClass(genericClass); TableInfo tableInfo = TableInfoFactory.ofEntityClass(genericClass);
// 构建嵌套类型的 ResultMap 对象也就是 <collection> 标签下的内容 // 构建嵌套类型的 ResultMap 对象也就是 <collection> 标签下的内容
ResultMap nestedResultMap = tableInfo.doBuildResultMap(configuration, resultMapIds, true, nestedPrefix); ResultMap nestedResultMap = tableInfo.doBuildResultMap(configuration, resultMapIds, existedColumns, true, nestedPrefix);
if (nestedResultMap != null) { if (nestedResultMap != null) {
resultMappings.add(new ResultMapping.Builder(configuration, field.getName()) resultMappings.add(new ResultMapping.Builder(configuration, field.getName())
.javaType(field.getType()) .javaType(field.getType())
@ -1077,8 +1123,9 @@ public class TableInfo {
} }
private void doBuildColumnResultMapping(Configuration configuration, List<ResultMapping> resultMappings private void doBuildColumnResultMapping(Configuration configuration, List<ResultMapping> resultMappings
, ColumnInfo columnInfo, List<ResultFlag> flags) { , Set<String> existedColumns, ColumnInfo columnInfo, List<ResultFlag> flags, boolean isNested) {
if (!isNested) {
// userName -> user_name // userName -> user_name
resultMappings.add(new ResultMapping.Builder(configuration resultMappings.add(new ResultMapping.Builder(configuration
, columnInfo.property , columnInfo.property
@ -1088,7 +1135,9 @@ public class TableInfo {
.flags(flags) .flags(flags)
.typeHandler(columnInfo.buildTypeHandler(configuration)) .typeHandler(columnInfo.buildTypeHandler(configuration))
.build()); .build());
}
if (existedColumns.contains(columnInfo.column)) {
// userName -> tb_user$user_name // userName -> tb_user$user_name
resultMappings.add(new ResultMapping.Builder(configuration resultMappings.add(new ResultMapping.Builder(configuration
, columnInfo.property , columnInfo.property
@ -1098,6 +1147,7 @@ public class TableInfo {
.flags(flags) .flags(flags)
.typeHandler(columnInfo.buildTypeHandler(configuration)) .typeHandler(columnInfo.buildTypeHandler(configuration))
.build()); .build());
}
if (!Objects.equals(columnInfo.column, columnInfo.property)) { if (!Objects.equals(columnInfo.column, columnInfo.property)) {
// userName -> userName // userName -> userName

View File

@ -17,13 +17,16 @@
package com.mybatisflex.test.mapper; package com.mybatisflex.test.mapper;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.test.alisa.SysUser; import com.mybatisflex.test.alisa.SysUser;
import org.apache.ibatis.mapping.ResultMap;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import java.util.Arrays;
import java.util.List; import java.util.List;
import static com.mybatisflex.core.query.QueryMethods.column; import static com.mybatisflex.core.query.QueryMethods.column;
@ -120,12 +123,25 @@ class AlisaTest {
void test06() { void test06() {
QueryWrapper queryWrapper = QueryWrapper.create() QueryWrapper queryWrapper = QueryWrapper.create()
// SELECT 里没有重名列 例如id // SELECT 里没有重名列 例如id
// 不指定别名会映射到嵌套对象里面去
.select(SYS_USER.ID, SYS_USER.USER_NAME, SYS_USER.AGE, SYS_USER.BIRTHDAY) .select(SYS_USER.ID, SYS_USER.USER_NAME, SYS_USER.AGE, SYS_USER.BIRTHDAY)
.select(SYS_ROLE.CREATE_BY.as("sys_role$create_by")) .select(SYS_ROLE.CREATE_BY.as("sys_role$create_by"))
.from(SYS_USER.as("u")) .from(SYS_USER.as("u"))
.leftJoin(SYS_ROLE).as("r").on(SYS_USER.ID.eq(SYS_ROLE.ID)); .leftJoin(SYS_ROLE).as("r").on(SYS_USER.ID.eq(SYS_ROLE.ID));
Object[] objects = FlexGlobalConfig.getDefaultConfig()
.getConfiguration()
.getResultMaps()
.toArray();
Object[] resultMaps = Arrays.stream(objects)
.filter(e -> e instanceof ResultMap)
.map(e -> (ResultMap) e)
.filter(e -> e.getId().contains("Sys"))
.filter(e -> !e.getId().contains("select"))
.toArray();
System.out.println(resultMaps.length);
printList(queryWrapper); printList(queryWrapper);
} }