fix: 自动映射无法对 List<String> 进行自动忽略的问题;close #I7X7G7 close #I7XBQS

This commit is contained in:
开源海哥 2023-08-31 14:58:09 +08:00
parent ea1f3ad650
commit 0415a0f593
5 changed files with 1343 additions and 12 deletions

View File

@ -19,21 +19,26 @@ import com.mybatisflex.core.transaction.TransactionContext;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.resultset.DefaultResultSetHandler;
import org.apache.ibatis.executor.resultset.ResultSetWrapper;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.ResultMapping;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.type.TypeHandler;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
/**
* @author michael
* 用于增强对 Cursor 查询处理
* 用于增强对 Cursor 查询处理以及 List<String> 的自动映射问题
*/
public class FlexResultSetHandler extends DefaultResultSetHandler {
public class FlexResultSetHandler extends FlexDefaultResultSetHandler {
public FlexResultSetHandler(Executor executor, MappedStatement mappedStatement, ParameterHandler parameterHandler
, ResultHandler<?> resultHandler, BoundSql boundSql, RowBounds rowBounds) {
@ -57,6 +62,43 @@ public class FlexResultSetHandler extends DefaultResultSetHandler {
}
/**
* 修复当实体类中存在 List<String> 或者 List<Integer> 等自动映射出错的问题
* 本质问题应该出现 mybatis 判断有误
*
* https://gitee.com/mybatis-flex/mybatis-flex/issues/I7XBQS
* https://gitee.com/mybatis-flex/mybatis-flex/issues/I7X7G7
*
* @param rsw
* @param resultMap
* @param columnPrefix
* @throws SQLException
*/
@Override
protected Object createPrimitiveResultObject(ResultSetWrapper rsw, ResultMap resultMap, String columnPrefix)
throws SQLException {
final Class<?> resultType = resultMap.getType();
final String columnName;
final TypeHandler<?> typeHandler;
if (!resultMap.getResultMappings().isEmpty()) {
final List<ResultMapping> resultMappingList = resultMap.getResultMappings();
final ResultMapping mapping = resultMappingList.get(0);
columnName = prependPrefix(mapping.getColumn(), columnPrefix);
typeHandler = mapping.getTypeHandler();
} else {
columnName = rsw.getColumnNames().get(0);
typeHandler = rsw.getTypeHandler(resultType, columnName);
}
List<String> mappedColumnNames = rsw.getMappedColumnNames(resultMap, columnPrefix);
if (columnName != null && mappedColumnNames.contains(columnName.toUpperCase(Locale.ENGLISH))) {
return typeHandler.getResult(rsw.getResultSet(), columnName);
}
return null;
}
static class FlexCursor<T> implements Cursor<T> {
private final Cursor<T> originalCursor;
@ -68,8 +110,7 @@ public class FlexResultSetHandler extends DefaultResultSetHandler {
@Override
public void close() {
// do nothing
// TransactionContext 去关闭
// do nothing TransactionContext 去关闭
}
@Override

View File

@ -39,7 +39,6 @@ import org.apache.ibatis.reflection.Reflector;
import org.apache.ibatis.reflection.ReflectorFactory;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.UnknownTypeHandler;
import org.apache.ibatis.util.MapUtil;
import java.lang.reflect.Field;
@ -657,7 +656,7 @@ public class TableInfo {
if (enumWrapper.hasEnumValueAnnotation()) {
value = enumWrapper.getEnumValue((Enum) value);
} else {
value = ((Enum<?>)value).name();
value = ((Enum<?>) value).name();
}
}
}
@ -1038,12 +1037,16 @@ public class TableInfo {
// List<String> List<Integer>
String columnName = TableInfoFactory.getColumnName(camelToUnderline, field, field.getAnnotation(Column.class));
// 映射 <result column="..."/>
String nestedResultMapId = entityClass.getName() + "." + field.getName();
ResultMapping resultMapping = new ResultMapping.Builder(configuration, null)
.column(columnName)
.typeHandler(new UnknownTypeHandler(configuration))
.typeHandler(configuration.getTypeHandlerRegistry().getTypeHandler(genericClass))
.build();
ResultMap nestedResultMap = new ResultMap.Builder(configuration, nestedResultMapId, genericClass, Collections.singletonList(resultMapping)).build();
String nestedResultMapId = entityClass.getName() + "." + field.getName();
ResultMap nestedResultMap = new ResultMap.Builder(configuration, nestedResultMapId, genericClass
, Collections.singletonList(resultMapping)).build();
configuration.addResultMap(nestedResultMap);
// 映射 <collection property="..." ofType="genericClass">
resultMappings.add(new ResultMapping.Builder(configuration, field.getName())

View File

@ -48,6 +48,11 @@ public class AccountDTO {
private List<Article> articles;
// @Column(ignore = true)
private List<String> permissions;
private String testOtherField;
public Long getId() {
return id;
@ -105,6 +110,32 @@ public class AccountDTO {
this.articles = articles;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getTestOtherField() {
return testOtherField;
}
public void setTestOtherField(String testOtherField) {
this.testOtherField = testOtherField;
}
public List<String> getPermissions() {
return permissions;
}
public void setPermissions(List<String> permissions) {
this.permissions = permissions;
}
@Override
public String toString() {
return "AccountDTO{" +
@ -115,7 +146,7 @@ public class AccountDTO {
", options=" + options +
", isDelete=" + isDelete +
", articles=" + articles +
", permissions=" + permissions +
'}';
}
}

View File

@ -178,7 +178,12 @@ public class AccountTester {
@Test
public void testSelectAsToDTO() {
List<AccountDTO> accountDTOS = accountMapper.selectListByQueryAs(QueryWrapper.create(), AccountDTO.class);
QueryWrapper queryWrapper = QueryWrapper.create();
// queryWrapper.select(ACCOUNT.ALL_COLUMNS,ARTICLE.TITLE.as(AccountDTO::getPermissions))
queryWrapper.select(ACCOUNT.ALL_COLUMNS,ACCOUNT.USER_NAME.as(AccountDTO::getTestOtherField))
// queryWrapper.select(ACCOUNT.ALL_COLUMNS)
.from(ACCOUNT).leftJoin(ARTICLE).on(ACCOUNT.ID.eq(ARTICLE.ACCOUNT_ID));
List<AccountDTO> accountDTOS = accountMapper.selectListByQueryAs(queryWrapper, AccountDTO.class);
System.out.println(accountDTOS);
}