定义接口规范
public interface TranslationEnum {
Object getValue(Object code);
}
定义运行时注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EnableConvert {
}
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ConvertEnum {
Class<? extends TranslationEnum> clazz();
String codeField();
}
POJO及枚举配置
@EnableConvert
public class TestEntity {
@ConvertEnum(clazz = TestEnum.class, codeField = "age")
private String name;
private Integer age;
}
@Getter
public enum TestEnum implements TranslationEnum{
TEST_1(1, "test1"),
TEST_2(2, "test2"),
;
private Integer code;
private String value;
TestEnum(Integer code, String value) {
this.code = code;
this.value = value;
}
private static final Map<Object, String> VALUE_MAP = new HashMap<>(TestEnum.values().length * 4 / 3);
static {
for (TestEnum value : TestEnum.values()) {
VALUE_MAP.put(value.code, value.value);
}
}
@Override
public Object getValue(Object code) {
return VALUE_MAP.get(code);
}
}
工具类具体实现
@Slf4j
public class ConvertUtils {
private ConvertUtils() {
}
public static <T> void convertEnums(T t) {
if (Objects.isNull(t)) {
return;
}
for (Class<?> clazz = t.getClass(); !clazz.equals(Object.class); clazz = clazz.getSuperclass()) {
if (clazz.isAnnotationPresent(EnableConvert.class)) {
Field[] fields = clazz.getDeclaredFields();
Field.setAccessible(fields, true);
for (Field field : fields) {
ConvertEnum convertEnum = field.getAnnotation(ConvertEnum.class);
if (Objects.nonNull(convertEnum)) {
Class<? extends TranslationEnum> enumClazz = convertEnum.clazz();
try {
Field codeField = clazz.getDeclaredField(convertEnum.codeField());
codeField.setAccessible(true);
Object code = codeField.get(t);
if (!enumClazz.isEnum()) {
throw new RuntimeException(enumClazz.getName() + "非枚举类型");
} else if (enumClazz.getEnumConstants().length == 0) {
throw new RuntimeException(enumClazz.getName() + "无实例");
}
TranslationEnum translationEnum = enumClazz.getEnumConstants()[0];
if (Objects.nonNull(translationEnum)) {
Object value = translationEnum.getValue(code);
field.set(t, value);
}
} catch (Exception e) {
LogUtils.debug("convert exception:" + e.getMessage(), e);
}
}
}
}
}
}
public static <T> void convertEnums(List<T> list) {
if (list.isEmpty()) {
return;
}
list.forEach(ConvertUtils::convertEnums);
}
}
mybatis拦截器转义结果集
@Configuration
public class MyBatisTranslateConfig {
@Bean
public TranslateInterceptor getInterceptor() {
return new TranslateInterceptor();
}
@Intercepts({
@Signature(
method = "query",
type = Executor.class,
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
@Signature(
type = ResultSetHandler.class,
method = "handleResultSets",
args = Statement.class)
})
private static class TranslateInterceptor implements Interceptor {
@Override
@SuppressWarnings("unchecked")
public Object intercept(Invocation invocation) throws Throwable {
List<Object> objects = (List<Object>) invocation.proceed();
ConvertUtils.convertEnums(objects);
return objects;
}
}
}