diff --git a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/EnumValue.java b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/EnumValue.java
new file mode 100644
index 00000000..342e8e27
--- /dev/null
+++ b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/EnumValue.java
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
+ *
+ * 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
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.annotation;
+
+import java.lang.annotation.*;
+
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+public @interface EnumValue {
+
+}
\ No newline at end of file
diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/handler/CompositeEnumTypeHandler.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/handler/CompositeEnumTypeHandler.java
new file mode 100644
index 00000000..9695009b
--- /dev/null
+++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/handler/CompositeEnumTypeHandler.java
@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
+ *
+ * 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
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.handler;
+
+import com.mybatisflex.annotation.EnumValue;
+import com.mybatisflex.core.util.ClassUtil;
+import org.apache.ibatis.type.EnumTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.TypeHandler;
+
+import java.lang.reflect.Field;
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+
+public class CompositeEnumTypeHandler> implements TypeHandler {
+
+ private final TypeHandler delegate;
+
+ public CompositeEnumTypeHandler(Class enumClass) {
+ List enumDbValueFields = ClassUtil.getAllFields(enumClass, f -> f.getAnnotation(EnumValue.class) != null);
+ if (enumDbValueFields.isEmpty()) {
+ delegate = new EnumTypeHandler<>(enumClass);
+ } else {
+ delegate = new FlexEnumTypeHandler<>(enumClass);
+ }
+ }
+
+ @Override
+ public void setParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
+ delegate.setParameter(ps, i, parameter, jdbcType);
+ }
+
+ @Override
+ public E getResult(ResultSet rs, String columnName) throws SQLException {
+ return delegate.getResult(rs, columnName);
+ }
+
+ @Override
+ public E getResult(ResultSet rs, int columnIndex) throws SQLException {
+ return delegate.getResult(rs, columnIndex);
+ }
+
+ @Override
+ public E getResult(CallableStatement cs, int columnIndex) throws SQLException {
+ return delegate.getResult(cs, columnIndex);
+ }
+}
diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/handler/FlexEnumTypeHandler.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/handler/FlexEnumTypeHandler.java
new file mode 100644
index 00000000..1d11eeb8
--- /dev/null
+++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/handler/FlexEnumTypeHandler.java
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
+ *
+ * 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
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.handler;
+
+import com.mybatisflex.annotation.EnumValue;
+import com.mybatisflex.core.exception.FlexExceptions;
+import com.mybatisflex.core.util.ClassUtil;
+import com.mybatisflex.core.util.StringUtil;
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+
+public class FlexEnumTypeHandler> extends BaseTypeHandler {
+
+ private Class> enumPropertyType;
+ private E[] enums;
+ private Method getter;
+
+ public FlexEnumTypeHandler(Class enumClass) {
+
+ List allFields = ClassUtil.getAllFields(enumClass, field -> field.getAnnotation(EnumValue.class) != null);
+ Field field = allFields.get(0);
+
+ List allMethods = ClassUtil.getAllMethods(enumClass, method -> {
+ String methodName = method.getName();
+ return methodName.equals("get" + StringUtil.firstCharToUpperCase(field.getName()));
+ });
+
+ enumPropertyType = field.getType();
+ enums = enumClass.getEnumConstants();
+ getter = allMethods.get(0);
+ }
+
+
+ @Override
+ public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
+ Object value = getValue(parameter);
+ if (jdbcType == null) {
+ ps.setObject(i, value);
+ } else {
+ ps.setObject(i, value, jdbcType.TYPE_CODE);
+ }
+ }
+
+
+ private Object getValue(Object object) {
+ try {
+ return this.getter.invoke(object);
+ } catch (Exception e) {
+ throw FlexExceptions.wrap(e);
+ }
+ }
+
+
+ @Override
+ public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
+ Object value = rs.getObject(columnName, this.enumPropertyType);
+ if (null == value && rs.wasNull()) {
+ return null;
+ }
+ return convertToEnum(value);
+ }
+
+
+ @Override
+ public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+ Object value = rs.getObject(columnIndex, this.enumPropertyType);
+ if (null == value && rs.wasNull()) {
+ return null;
+ }
+ return convertToEnum(value);
+ }
+
+
+ @Override
+ public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+ Object value = cs.getObject(columnIndex, this.enumPropertyType);
+ if (null == value && cs.wasNull()) {
+ return null;
+ }
+ return convertToEnum(value);
+ }
+
+
+ private E convertToEnum(Object value) {
+ for (E e : enums) {
+ if (value.equals(getValue(e))) {
+ return e;
+ }
+ }
+ return null;
+ }
+}
diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/ColumnInfo.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/ColumnInfo.java
index f039172d..8378e646 100644
--- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/ColumnInfo.java
+++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/ColumnInfo.java
@@ -15,6 +15,7 @@
*/
package com.mybatisflex.core.table;
+import com.mybatisflex.core.handler.CompositeEnumTypeHandler;
import com.mybatisflex.core.mask.MaskTypeHandler;
import com.mybatisflex.core.util.StringUtil;
import org.apache.ibatis.type.JdbcType;
@@ -51,7 +52,6 @@ public class ColumnInfo {
protected String maskType;
-
public String getColumn() {
return column;
}
@@ -87,12 +87,16 @@ public class ColumnInfo {
public TypeHandler buildTypeHandler() {
//优先使用自定义的 typeHandler
- if (typeHandler != null){
+ if (typeHandler != null) {
return typeHandler;
}
+ //枚举
+ else if (propertyType.isEnum()) {
+ typeHandler = new CompositeEnumTypeHandler(propertyType);
+ }
//若用户未定义 typeHandler,而配置了数据脱敏,则使用脱敏的 handler 处理
- else if (StringUtil.isNotBlank(maskType)){
- typeHandler = new MaskTypeHandler(maskType);
+ else if (StringUtil.isNotBlank(maskType)) {
+ typeHandler = new MaskTypeHandler(maskType);
}
return typeHandler;
diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfoFactory.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfoFactory.java
index 4094d8b7..3459b7f2 100644
--- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfoFactory.java
+++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfoFactory.java
@@ -173,6 +173,7 @@ public class TableInfoFactory {
//未配置 typeHandler 的情况下,只支持基本数据类型,不支持比如 list set 或者自定义的类等
if ((column == null || column.typeHandler() == UnknownTypeHandler.class)
+ && !field.getType().isEnum()
&& !defaultSupportColumnTypes.contains(field.getType())) {
continue;
}
diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ClassUtil.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ClassUtil.java
index 675bd76a..23fad6a7 100644
--- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ClassUtil.java
+++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ClassUtil.java
@@ -144,22 +144,29 @@ public class ClassUtil {
public static List getAllFields(Class> cl) {
List fields = new ArrayList<>();
- doGetFields(cl, fields);
+ doGetFields(cl, fields, null);
return fields;
}
+ public static List getAllFields(Class> cl, Predicate predicate) {
+ List fields = new ArrayList<>();
+ doGetFields(cl, fields, predicate);
+ return fields;
+ }
- private static void doGetFields(Class> cl, List fields) {
+ private static void doGetFields(Class> cl, List fields, Predicate predicate) {
if (cl == null || cl == Object.class) {
return;
}
Field[] declaredFields = cl.getDeclaredFields();
for (Field declaredField : declaredFields) {
- fields.add(declaredField);
+ if (predicate == null || predicate.test(declaredField)) {
+ fields.add(declaredField);
+ }
}
- doGetFields(cl.getSuperclass(), fields);
+ doGetFields(cl.getSuperclass(), fields, predicate);
}
public static List getAllMethods(Class> cl) {
@@ -168,26 +175,26 @@ public class ClassUtil {
return methods;
}
- public static List getAllMethods(Class> cl, Predicate tester) {
+ public static List getAllMethods(Class> cl, Predicate predicate) {
List methods = new ArrayList<>();
- doGetMethods(cl, methods, tester);
+ doGetMethods(cl, methods, predicate);
return methods;
}
- private static void doGetMethods(Class> cl, List methods, Predicate tester) {
+ private static void doGetMethods(Class> cl, List methods, Predicate predicate) {
if (cl == null || cl == Object.class) {
return;
}
Method[] declaredMethods = cl.getDeclaredMethods();
for (Method method : declaredMethods) {
- if (tester == null || tester.test(method)) {
+ if (predicate == null || predicate.test(method)) {
methods.add(method);
}
}
- doGetMethods(cl.getSuperclass(), methods, tester);
+ doGetMethods(cl.getSuperclass(), methods, predicate);
}
}