add: Row.toObject() method

This commit is contained in:
开源海哥 2023-04-13 14:24:25 +08:00
parent 139737adc2
commit 757192edd7
3 changed files with 108 additions and 8 deletions

View File

@ -19,10 +19,7 @@ import com.mybatisflex.core.javassist.ModifyAttrsRecord;
import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.table.TableInfo;
import com.mybatisflex.core.table.TableInfoFactory;
import com.mybatisflex.core.util.ArrayUtil;
import com.mybatisflex.core.util.ConvertUtil;
import com.mybatisflex.core.util.SqlUtil;
import com.mybatisflex.core.util.StringUtil;
import com.mybatisflex.core.util.*;
import java.math.BigDecimal;
import java.math.BigInteger;
@ -282,6 +279,12 @@ public class Row extends HashMap<String, Object> implements ModifyAttrsRecord {
return tableInfo.newInstanceByRow(this);
}
public <T> T toObject(Class<T> objectClass) {
Object instance = ClassUtil.newInstance(objectClass);
RowSetter.setObject(this, instance);
return (T) instance;
}
public Map<String, Object> toCamelKeysMap() {
Map<String, Object> ret = new HashMap<>();
for (String key : keySet()) {

View File

@ -0,0 +1,71 @@
/**
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.core.row;
import com.mybatisflex.core.util.ClassUtil;
import com.mybatisflex.core.util.ConvertUtil;
import com.mybatisflex.core.util.StringUtil;
import org.apache.ibatis.util.MapUtil;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
class RowSetter {
static Map<Class<?>, Map<String, Method>> getterMethods = new ConcurrentHashMap<>();
static void setObject(Row row, Object toObject) {
Map<String, Method> setterMethods = getSetterMethods(toObject.getClass());
row.forEach((column, columnValue) -> {
Method setter = setterMethods.get(column);
try {
if (setter != null) {
Object value = ConvertUtil.convert(columnValue, setter.getParameterTypes()[0]);
setter.invoke(toObject, value);
}
} catch (Exception e) {
throw new RuntimeException("Can not invoke method: " + setter);
}
});
}
private static Map<String, Method> getSetterMethods(Class<?> aClass) {
return MapUtil.computeIfAbsent(getterMethods, aClass, aClass1 -> {
Map<String, Method> getterMethodsMapping = new HashMap<>();
List<Method> setters = ClassUtil.getAllMethods(aClass1,
method -> method.getName().startsWith("set")
&& method.getParameterCount() == 1
&& Modifier.isPublic(method.getModifiers())
);
for (Method setter : setters) {
String column = setter.getName().substring(3);
getterMethodsMapping.put(column, setter);
getterMethodsMapping.put(column.toLowerCase(), setter);
getterMethodsMapping.put(column.toUpperCase(), setter);
getterMethodsMapping.put(StringUtil.firstCharToLowerCase(column), setter);
getterMethodsMapping.put(StringUtil.camelToUnderline(column), setter);
getterMethodsMapping.put(StringUtil.camelToUnderline(column).toUpperCase(), setter);
getterMethodsMapping.put(StringUtil.underlineToCamel(column), setter);
}
return getterMethodsMapping;
});
}
}

View File

@ -16,13 +16,11 @@
package com.mybatisflex.core.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
/**
* 类实例创建者创建者
@ -164,4 +162,32 @@ public class ClassUtil {
doGetFields(cl.getSuperclass(), fields);
}
public static List<Method> getAllMethods(Class<?> cl) {
List<Method> methods = new ArrayList<>();
doGetMethods(cl, methods, null);
return methods;
}
public static List<Method> getAllMethods(Class<?> cl, Predicate<Method> tester) {
List<Method> methods = new ArrayList<>();
doGetMethods(cl, methods, tester);
return methods;
}
private static void doGetMethods(Class<?> cl, List<Method> methods, Predicate<Method> tester) {
if (cl == null || cl == Object.class) {
return;
}
Method[] declaredMethods = cl.getDeclaredMethods();
for (Method method : declaredMethods) {
if (tester == null || tester.test(method)) {
methods.add(method);
}
}
doGetMethods(cl.getSuperclass(), methods, tester);
}
}