枚举在数据库中,通常以数值存储。为了方便枚举的使用,抽象超类SerializableEnum
实现序列化和反序列化。
定义超类
public interface SerializableEnum {
Map<Map.Entry<?, ?>, SerializableEnum> CACHE = new HashMap<>();
int getCode();
/**
* 静态构造函数
*/
static <T extends Enum<?> & SerializableEnum> T from(Class<T> cls, Integer code) {
if (code == null || cls == null) {
return null;
}
ImmutablePair<Class<T>, Integer> key = ImmutablePair.of(cls, code);
if (CACHE.containsKey(key)) {
return (T) CACHE.get(key);
}
// 没有缓存
BeanInfo beanInfo = null;
try {
beanInfo = Introspector.getBeanInfo(cls, Object.class);
} catch (IntrospectionException e) {
e.printStackTrace();
return null;
}
MethodDescriptor[] methodDescriptors = beanInfo.getMethodDescriptors();
if (methodDescriptors != null && methodDescriptors.length > 0) {
Optional<MethodDescriptor> valuesMethod = Arrays.stream(methodDescriptors)
.filter(m -> Objects.equals(m.getName(), "values"))
.findAny();
if (valuesMethod.isPresent()) {
T[] invoke = null;
try {
invoke = (T[]) valuesMethod.get().getMethod().invoke(cls);
} catch (IllegalAccessException | InvocationTargetException e) {
return null;
}
return Arrays.stream(invoke)
.filter(it -> Objects.deepEquals(it.getCode(), code))
.peek(it -> CACHE.put(
key, it
))
.findAny()
.orElse(null);
}
}
return null;
}
}
具体枚举
public enum GroupRole implements SerializableEnum {
/**
* 群主
*/
OWNER(1),
/**
* 管理员
*/
MANAGER(2),
/**
* 普通成员
*/
MEMBER(3);
@Getter
private final int code;
GroupRole(int code) {
this.code = code;
}
}
mybatis typehandler
通用转换器
public abstract class SerializableEnumTypeHandler<T extends Enum<?> & SerializableEnum> extends BaseTypeHandler<T> {
private Class<T> argTypeOfImplClass;
public SerializableEnumTypeHandler() {
ResolvableType resolvableType = ResolvableType.forType(this.getClass().getGenericSuperclass());
Class<?>[] classes = resolvableType.resolveGenerics();
argTypeOfImplClass = (Class<T>) classes[0];
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
ps.setInt(i, parameter.getCode());
}
@Override
public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
return SerializableEnum.from(argTypeOfImplClass, rs.getInt(columnName));
}
@Override
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return SerializableEnum.from(argTypeOfImplClass, rs.getInt(columnIndex));
}
@Override
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return null;
}
}
具体 typehandler
@MappedJdbcTypes(JdbcType.INTEGER)
public class GroupMemberRoleTypeHandler extends SerializableEnumTypeHandler<GroupMemberRole> {
}
网友评论