diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ConvertUtil.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ConvertUtil.java index 157ffeb7..2455015c 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ConvertUtil.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ConvertUtil.java @@ -15,6 +15,11 @@ */ package com.mybatisflex.core.util; +import com.mybatisflex.annotation.EnumValue; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.math.BigInteger; import java.time.LocalDate; @@ -22,11 +27,13 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.temporal.Temporal; import java.util.Date; +import java.util.List; +import java.util.Objects; public class ConvertUtil { - public static Object convert(Object value, Class targetClass) { + public static Object convert(Object value, Class targetClass) { if (value == null && targetClass.isPrimitive()) { return getPrimitiveDefaultValue(targetClass); } @@ -87,12 +94,60 @@ public class ConvertUtil { return ((Number) value).shortValue(); } return Short.parseShort(value.toString()); + } else if (targetClass.isEnum()) { + Object[] enumConstants = targetClass.getEnumConstants(); + List allFields = ClassUtil.getAllFields(targetClass, field -> field.getAnnotation(EnumValue.class) != null); + if (allFields.size() == 1) { + Field field = allFields.get(0); + + String fieldGetterName = "get" + StringUtil.firstCharToUpperCase(field.getName()); + List allMethods = ClassUtil.getAllMethods(targetClass, method -> { + String methodName = method.getName(); + return methodName.equals(fieldGetterName); + }); + + //getter + if (allMethods.size() == 1) { + Method getter = allMethods.get(0); + for (Object enumConstant : enumConstants) { + try { + Object enumValue = getter.invoke(enumConstant); + if (Objects.equals(enumValue, value)) { + return enumConstant; + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + //public field + else if (Modifier.isPublic(field.getModifiers())) { + for (Object enumConstant : enumConstants) { + if (Objects.equals(readPublicField(field, enumConstant), value)) { + return enumConstant; + } + } + } + } else if (value instanceof String) { + return Enum.valueOf(targetClass, value.toString()); + } } + throw new IllegalArgumentException("\"" + targetClass.getName() + "\" can not be parsed."); } + private static Object readPublicField(Field field, Object target) { + try { + return field.get(target); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + //Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE public static Object getPrimitiveDefaultValue(Class paraClass) { if (paraClass == int.class || paraClass == long.class || paraClass == float.class || paraClass == double.class) { @@ -151,19 +206,19 @@ public class ConvertUtil { public static BigInteger toBigInteger(Object b) { if (b instanceof BigInteger) { - return (BigInteger)b; + return (BigInteger) b; } // 数据类型 id(19 number)在 Oracle Jdbc 下对应的是 BigDecimal, // 但是在 MySql 下对应的是 BigInteger,这会导致在 MySql 下生成的代码无法在 Oracle 数据库中使用 if (b instanceof BigDecimal) { - return ((BigDecimal)b).toBigInteger(); + return ((BigDecimal) b).toBigInteger(); } else if (b instanceof Number) { - return BigInteger.valueOf(((Number)b).longValue()); + return BigInteger.valueOf(((Number) b).longValue()); } else if (b instanceof String) { - return new BigInteger((String)b); + return new BigInteger((String) b); } - return (BigInteger)b; + return (BigInteger) b; } public static Float toFloat(Object f) {