add auto join mapping support

This commit is contained in:
开源海哥 2023-05-29 18:49:03 +08:00
parent 81d676dcbb
commit f1c97d7dcd
4 changed files with 170 additions and 29 deletions

View File

@ -95,6 +95,8 @@ public class TableInfo {
private List<UpdateListener> onUpdateListeners; private List<UpdateListener> onUpdateListeners;
private List<SetListener> onSetListeners; private List<SetListener> onSetListeners;
private Map<String, Class<?>> joinTypes;
private final ReflectorFactory reflectorFactory = new BaseReflectorFactory() { private final ReflectorFactory reflectorFactory = new BaseReflectorFactory() {
@Override @Override
@ -270,6 +272,20 @@ public class TableInfo {
return propertyColumnMapping.get(property); return propertyColumnMapping.get(property);
} }
public Map<String, Class<?>> getJoinTypes() {
return joinTypes;
}
public void setJoinTypes(Map<String, Class<?>> joinTypes) {
this.joinTypes = joinTypes;
}
public void addJoinType(String fieldName, Class<?> clazz) {
if (joinTypes == null) {
joinTypes = new HashMap<>();
}
joinTypes.put(fieldName, clazz);
}
void setColumnInfoList(List<ColumnInfo> columnInfoList) { void setColumnInfoList(List<ColumnInfo> columnInfoList) {
this.columnInfoList = columnInfoList; this.columnInfoList = columnInfoList;
@ -640,17 +656,17 @@ public class TableInfo {
List<ResultMapping> resultMappings = new ArrayList<>(); List<ResultMapping> resultMappings = new ArrayList<>();
for (ColumnInfo columnInfo : columnInfoList) { for (ColumnInfo columnInfo : columnInfoList) {
ResultMapping mapping = new ResultMapping.Builder(configuration, columnInfo.getProperty(), ResultMapping mapping = new ResultMapping.Builder(configuration, columnInfo.property,
columnInfo.getColumn(), columnInfo.getPropertyType()) columnInfo.column, columnInfo.propertyType)
.jdbcType(columnInfo.getJdbcType()) .jdbcType(columnInfo.getJdbcType())
.typeHandler(columnInfo.buildTypeHandler()) .typeHandler(columnInfo.buildTypeHandler())
.build(); .build();
resultMappings.add(mapping); resultMappings.add(mapping);
//add property mapper for sql as ... //add property mapper for sql: select xxx as property ...
if (!Objects.equals(columnInfo.getColumn(), columnInfo.getProperty())) { if (!Objects.equals(columnInfo.getColumn(), columnInfo.getProperty())) {
ResultMapping propertyMapping = new ResultMapping.Builder(configuration, columnInfo.getProperty(), ResultMapping propertyMapping = new ResultMapping.Builder(configuration, columnInfo.property,
columnInfo.getProperty(), columnInfo.getPropertyType()) columnInfo.property, columnInfo.propertyType)
.jdbcType(columnInfo.getJdbcType()) .jdbcType(columnInfo.getJdbcType())
.typeHandler(columnInfo.buildTypeHandler()) .typeHandler(columnInfo.buildTypeHandler())
.build(); .build();
@ -659,8 +675,8 @@ public class TableInfo {
} }
for (IdInfo idInfo : primaryKeyList) { for (IdInfo idInfo : primaryKeyList) {
ResultMapping mapping = new ResultMapping.Builder(configuration, idInfo.getProperty(), ResultMapping mapping = new ResultMapping.Builder(configuration, idInfo.property,
idInfo.getColumn(), idInfo.getPropertyType()) idInfo.column, idInfo.propertyType)
.flags(CollectionUtil.newArrayList(ResultFlag.ID)) .flags(CollectionUtil.newArrayList(ResultFlag.ID))
.jdbcType(idInfo.getJdbcType()) .jdbcType(idInfo.getJdbcType())
.typeHandler(idInfo.buildTypeHandler()) .typeHandler(idInfo.buildTypeHandler())
@ -668,10 +684,51 @@ public class TableInfo {
resultMappings.add(mapping); resultMappings.add(mapping);
} }
if (joinTypes != null && !joinTypes.isEmpty()) {
joinTypes.forEach((fieldName, fieldType) -> {
TableInfo joinTableInfo = TableInfoFactory.ofEntityClass(fieldType);
List<ColumnInfo> joinTableInfoColumnInfoList = joinTableInfo.getColumnInfoList();
for (ColumnInfo joinColumnInfo : joinTableInfoColumnInfoList) {
if (!existColumn(resultMappings, joinColumnInfo.column)) {
ResultMapping mapping = new ResultMapping.Builder(configuration, fieldName + "." + joinColumnInfo.property,
joinColumnInfo.column, joinColumnInfo.propertyType)
.jdbcType(joinColumnInfo.jdbcType)
.typeHandler(joinColumnInfo.buildTypeHandler())
.build();
resultMappings.add(mapping);
}
//add property mapper for sql: select xxx as property ...
if (!existColumn(resultMappings, joinColumnInfo.property)) {
if (!Objects.equals(joinColumnInfo.column, joinColumnInfo.property)) {
ResultMapping propertyMapping = new ResultMapping.Builder(configuration, fieldName + "." + joinColumnInfo.property,
joinColumnInfo.property, joinColumnInfo.propertyType)
.jdbcType(joinColumnInfo.jdbcType)
.typeHandler(joinColumnInfo.buildTypeHandler())
.build();
resultMappings.add(propertyMapping);
}
}
}
});
}
return new ResultMap.Builder(configuration, resultMapId, entityClass, resultMappings).build(); return new ResultMap.Builder(configuration, resultMapId, entityClass, resultMappings).build();
} }
private static boolean existColumn(List<ResultMapping> resultMappings, String name) {
for (ResultMapping resultMapping : resultMappings) {
if (resultMapping.getColumn().equalsIgnoreCase(name)) {
return true;
}
}
return false;
}
private Object buildColumnSqlArg(MetaObject metaObject, String column) { private Object buildColumnSqlArg(MetaObject metaObject, String column) {
ColumnInfo columnInfo = columnInfoMapping.get(column); ColumnInfo columnInfo = columnInfoMapping.get(column);
Object value = getPropertyValue(metaObject, columnInfo.property); Object value = getPropertyValue(metaObject, columnInfo.property);

View File

@ -195,7 +195,7 @@ public class TableInfoFactory {
Set<String> defaultColumns = new LinkedHashSet<>(); Set<String> defaultColumns = new LinkedHashSet<>();
List<Field> entityFields = getAllFields(entityClass); List<Field> entityFields = getColumnFields(entityClass);
for (Field field : entityFields) { for (Field field : entityFields) {
@ -204,21 +204,21 @@ public class TableInfoFactory {
continue; // ignore continue; // ignore
} }
Class<?> fieldType = field.getType();
if (Modifier.isStatic(field.getModifiers())) { //满足一下 3 中情况不支持该类型
//ignore static field if ((column == null || column.typeHandler() == UnknownTypeHandler.class) // 未配置 typeHandler
&& !fieldType.isEnum() // 类型不是枚举
&& !defaultSupportColumnTypes.contains(fieldType) //默认的自动类型不包含该类型
) {
if (!Map.class.isAssignableFrom(fieldType)
&& !Collection.class.isAssignableFrom(fieldType)
&& !fieldType.isArray()) {
tableInfo.addJoinType(field.getName(), fieldType);
}
continue; continue;
} }
//未配置 typeHandler 的情况下只支持基本数据类型不支持比如 list set 或者自定义的类等
if ((column == null || column.typeHandler() == UnknownTypeHandler.class)
&& !field.getType().isEnum()
&& !defaultSupportColumnTypes.contains(field.getType())) {
continue;
}
//列名 //列名
String columnName = column != null && StringUtil.isNotBlank(column.value()) String columnName = column != null && StringUtil.isNotBlank(column.value())
? column.value() ? column.value()
@ -351,7 +351,7 @@ public class TableInfoFactory {
} }
public static List<Field> getAllFields(Class<?> entityClass) { public static List<Field> getColumnFields(Class<?> entityClass) {
List<Field> fields = new ArrayList<>(); List<Field> fields = new ArrayList<>();
doGetFields(entityClass, fields); doGetFields(entityClass, fields);
return fields; return fields;
@ -365,9 +365,11 @@ public class TableInfoFactory {
Field[] declaredFields = entityClass.getDeclaredFields(); Field[] declaredFields = entityClass.getDeclaredFields();
for (Field declaredField : declaredFields) { for (Field declaredField : declaredFields) {
if (!existName(fields, declaredField)) { if (Modifier.isStatic(declaredField.getModifiers())
fields.add(declaredField); || existName(fields, declaredField)) {
continue;
} }
fields.add(declaredField);
} }
doGetFields(entityClass.getSuperclass(), fields); doGetFields(entityClass.getSuperclass(), fields);

View File

@ -0,0 +1,65 @@
package com.mybatisflex.test;
public class ArticleDTO01 {
private Long id;
private Long accountId;
private String title;
private String content;
private Account account;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getAccountId() {
return accountId;
}
public void setAccountId(Long accountId) {
this.accountId = accountId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
@Override
public String toString() {
return "ArticleDTO01{" +
"id=" + id +
", accountId=" + accountId +
", title='" + title + '\'' +
", content='" + content + '\'' +
", account=" + account +
'}';
}
}

View File

@ -21,6 +21,8 @@ import com.mybatisflex.core.audit.ConsoleMessageCollector;
import com.mybatisflex.core.audit.MessageCollector; import com.mybatisflex.core.audit.MessageCollector;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.RowUtil;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
@ -112,20 +114,35 @@ public class EntityTestStarter {
// Object object = accountMapper.selectObjectByQuery(wrapper2); // Object object = accountMapper.selectObjectByQuery(wrapper2);
// System.out.println(object); // System.out.println(object);
// //
// QueryWrapper asWrapper = QueryWrapper.create()
// .select(ARTICLE.ALL_COLUMNS)
// .select(ACCOUNT.USER_NAME.as(ArticleDTO::getAuthorName)
// , ACCOUNT.AGE.as(ArticleDTO::getAuthorAge)
// , ACCOUNT.BIRTHDAY
// )
// .from(ARTICLE)
// .leftJoin(ACCOUNT).on(ARTICLE.ACCOUNT_ID.eq(ACCOUNT.ID))
//// .where(ACCOUNT.ID.ge(0));
// .where(ARTICLE.ID.ge(0).or(ACCOUNT.ID.ge(0)));
////
//// List<ArticleDTO> articleDTOS = accountMapper.selectListByQueryAs(asWrapper, ArticleDTO.class);
//// System.out.println(articleDTOS);
// Page<ArticleDTO> paginate = accountMapper.paginateAs(Page.of(1, 1), asWrapper, ArticleDTO.class);
// System.out.println(paginate);
QueryWrapper asWrapper = QueryWrapper.create() QueryWrapper asWrapper = QueryWrapper.create()
.select(ARTICLE.ALL_COLUMNS) .select(ARTICLE.ALL_COLUMNS,ACCOUNT.ALL_COLUMNS)
.select(ACCOUNT.USER_NAME.as(ArticleDTO::getAuthorName)
, ACCOUNT.AGE.as(ArticleDTO::getAuthorAge)
, ACCOUNT.BIRTHDAY
)
.from(ARTICLE) .from(ARTICLE)
.leftJoin(ACCOUNT).on(ARTICLE.ACCOUNT_ID.eq(ACCOUNT.ID)) .leftJoin(ACCOUNT).on(ARTICLE.ACCOUNT_ID.eq(ACCOUNT.ID))
// .where(ACCOUNT.ID.ge(0));
.where(ARTICLE.ID.ge(0).or(ACCOUNT.ID.ge(0))); .where(ARTICLE.ID.ge(0).or(ACCOUNT.ID.ge(0)));
RowUtil.printPretty(Db.selectListByQuery(asWrapper));
// //
// List<ArticleDTO> articleDTOS = accountMapper.selectListByQueryAs(asWrapper, ArticleDTO.class); // List<ArticleDTO> articleDTOS = accountMapper.selectListByQueryAs(asWrapper, ArticleDTO.class);
// System.out.println(articleDTOS); // System.out.println(articleDTOS);
Page<ArticleDTO> paginate = accountMapper.paginateAs(Page.of(1, 1), asWrapper, ArticleDTO.class); Page<ArticleDTO01> paginate = accountMapper.paginateAs(Page.of(1, 10), asWrapper, ArticleDTO01.class);
System.out.println(paginate); System.out.println(paginate);