fixed: 修复 entity 有配置 typeHandler 时,通过 RowUtil.toEntity 转换异常的问题; close #I70XGX

This commit is contained in:
开源海哥 2023-05-07 17:41:56 +08:00
parent ef99cae374
commit 78ef98b35a
3 changed files with 46 additions and 18 deletions

View File

@ -31,8 +31,7 @@ public class RowUtil {
static final String INDEX_SEPARATOR = "$"; static final String INDEX_SEPARATOR = "$";
private static final Map<Class<?>, Map<String, Method>> classGettersMapping = new ConcurrentHashMap<>(); private static final Map<Class<?>, Map<String, Method>> classSettersCache = new ConcurrentHashMap<>();
public static <T> T toObject(Row row, Class<T> objectClass) { public static <T> T toObject(Row row, Class<T> objectClass) {
return toObject(row, objectClass, 0); return toObject(row, objectClass, 0);
@ -41,15 +40,15 @@ public class RowUtil {
public static <T> T toObject(Row row, Class<T> objectClass, int index) { public static <T> T toObject(Row row, Class<T> objectClass, int index) {
T instance = ClassUtil.newInstance(objectClass); T instance = ClassUtil.newInstance(objectClass);
Map<String, Method> setterMethods = getSetterMethods(objectClass); Map<String, Method> classSetters = getSetterMethods(objectClass);
Set<String> rowKeys = row.keySet(); Set<String> rowKeys = row.keySet();
setterMethods.forEach((property, setter) -> { classSetters.forEach((property, setter) -> {
try { try {
if (index <= 0) { if (index <= 0) {
for (String rowKey : rowKeys) { for (String rowKey : rowKeys) {
if (property.equalsIgnoreCase(rowKey)) { if (property.equalsIgnoreCase(rowKey)) {
Object rowValue = row.get(rowKey); Object rowValue = row.get(rowKey);
Object value = ConvertUtil.convert(rowValue, setter.getParameterTypes()[0]); Object value = ConvertUtil.convert(rowValue, setter.getParameterTypes()[0], true);
setter.invoke(instance, value); setter.invoke(instance, value);
} }
} }
@ -60,7 +59,7 @@ public class RowUtil {
for (String rowKey : rowKeys) { for (String rowKey : rowKeys) {
if (newProperty.equalsIgnoreCase(rowKey)) { if (newProperty.equalsIgnoreCase(rowKey)) {
Object rowValue = row.get(rowKey); Object rowValue = row.get(rowKey);
Object value = ConvertUtil.convert(rowValue, setter.getParameterTypes()[0]); Object value = ConvertUtil.convert(rowValue, setter.getParameterTypes()[0], true);
setter.invoke(instance, value); setter.invoke(instance, value);
fillValue = true; fillValue = true;
break; break;
@ -129,7 +128,7 @@ public class RowUtil {
public static void registerMapping(Class<?> clazz, Map<String, Method> columnSetterMapping) { public static void registerMapping(Class<?> clazz, Map<String, Method> columnSetterMapping) {
classGettersMapping.put(clazz, columnSetterMapping); classSettersCache.put(clazz, columnSetterMapping);
} }
@ -204,7 +203,7 @@ public class RowUtil {
private static Map<String, Method> getSetterMethods(Class<?> aClass) { private static Map<String, Method> getSetterMethods(Class<?> aClass) {
return MapUtil.computeIfAbsent(classGettersMapping, aClass, aClass1 -> { return MapUtil.computeIfAbsent(classSettersCache, aClass, aClass1 -> {
Map<String, Method> columnSetterMapping = new HashMap<>(); Map<String, Method> columnSetterMapping = new HashMap<>();
List<Method> setters = ClassUtil.getAllMethods(aClass1, List<Method> setters = ClassUtil.getAllMethods(aClass1,
method -> method.getName().startsWith("set") method -> method.getName().startsWith("set")

View File

@ -38,6 +38,9 @@ import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandler; import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.util.MapUtil; import org.apache.ibatis.util.MapUtil;
import java.lang.reflect.Proxy;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -693,10 +696,7 @@ public class TableInfo {
if (index <= 0) { if (index <= 0) {
for (String rowKey : rowKeys) { for (String rowKey : rowKeys) {
if (column.equalsIgnoreCase(rowKey)) { if (column.equalsIgnoreCase(rowKey)) {
Object rowValue = row.get(rowKey); setInstancePropertyValue(row, instance, metaObject, columnInfo, rowKey);
Object value = ConvertUtil.convert(rowValue, metaObject.getSetterType(columnInfo.property));
value = invokeOnSetListener(instance, columnInfo.getProperty(), value);
metaObject.setValue(columnInfo.property, value);
} }
} }
} else { } else {
@ -705,10 +705,7 @@ public class TableInfo {
boolean fillValue = false; boolean fillValue = false;
for (String rowKey : rowKeys) { for (String rowKey : rowKeys) {
if (newColumn.equalsIgnoreCase(rowKey)) { if (newColumn.equalsIgnoreCase(rowKey)) {
Object rowValue = row.get(rowKey); setInstancePropertyValue(row, instance, metaObject, columnInfo, rowKey);
Object value = ConvertUtil.convert(rowValue, metaObject.getSetterType(columnInfo.property));
value = invokeOnSetListener(instance, columnInfo.getProperty(), value);
metaObject.setValue(columnInfo.property, value);
fillValue = true; fillValue = true;
break; break;
} }
@ -723,6 +720,31 @@ public class TableInfo {
} }
private void setInstancePropertyValue(Row row, Object instance, MetaObject metaObject, ColumnInfo columnInfo, String rowKey) {
Object rowValue = row.get(rowKey);
TypeHandler<?> typeHandler = columnInfo.buildTypeHandler();
if (typeHandler != null) {
try {
//通过 typeHandler 转换数据
rowValue = typeHandler.getResult(getResultSet(rowValue), 0);
} catch (SQLException e) {
//ignore
}
}
if (rowValue != null && !metaObject.getSetterType(columnInfo.property).isAssignableFrom(rowValue.getClass())) {
rowValue = ConvertUtil.convert(rowValue, metaObject.getSetterType(columnInfo.property), true);
}
rowValue = invokeOnSetListener(instance, columnInfo.getProperty(), rowValue);
metaObject.setValue(columnInfo.property, rowValue);
}
private ResultSet getResultSet(Object value) {
return (ResultSet) Proxy.newProxyInstance(TableInfo.class.getClassLoader(),
new Class[]{ResultSet.class}, (proxy, method, args) -> value);
}
/** /**
* 初始化乐观锁版本号 * 初始化乐观锁版本号
* *

View File

@ -34,6 +34,10 @@ public class ConvertUtil {
public static Object convert(Object value, Class targetClass) { public static Object convert(Object value, Class targetClass) {
return convert(value, targetClass, false);
}
public static Object convert(Object value, Class targetClass, boolean ignoreConvertError) {
if (value == null && targetClass.isPrimitive()) { if (value == null && targetClass.isPrimitive()) {
return getPrimitiveDefaultValue(targetClass); return getPrimitiveDefaultValue(targetClass);
} }
@ -134,8 +138,11 @@ public class ConvertUtil {
} }
} }
if (ignoreConvertError) {
throw new IllegalArgumentException("\"" + targetClass.getName() + "\" can not be parsed."); return null;
} else {
throw new IllegalArgumentException("Can not convert \"" + value + "\" to type\"" + targetClass.getName() + "\".");
}
} }