概述及背景
实际项目中,我们经常要处理一些枚举类型的数据。例如:订单的状态就分为已下单,已付款,已发货,订单完成等等很多状态,数据库中我们一般只存储的一个数字表示各种状态。但是,前台显示的话就需要显示名称给用户看,所以这中间就涉及到一个转化。我们见过太多了在前端通过 if, else 写死判断的。这样初期没啥,后期难以扩展及维护。针对这种情况,我们思考下能不能直接将枚举直接返回给前端,让前端显示时取value, 保存时传入key?这样的前端就不用写一堆判断了。
项目结构
项目的结构如上图所示,主要有7个部分,其中 1,4,7 是通过MyBatis操作数据库所必须的。我们只做简要分析,其余如通用的类型处理GeneralEnumHandler 和重写TypeHandlerRegistry类将是我们重点分析的对象。
枚举类基类
public interface BaseEnum<E extends Enum<?>, T> {
/**
* 真正与数据库进行映射的值
* @return
*/
T getKey();
/**
* 显示的信息
* @return
*/
String getValue();
}
枚举类基类作为万能的模板,主要定义了获取key和value的方法,供子类实现。然后其传入的泛型<E extends Enum<?>, T>
一个是枚举类自身,一个是枚举的key的类型。
通用类型处理器的设计
// 所有的自定义类型处理器都需要实现TypeHandler或者继承BaseTypeHandler类。
public class GeneralEnumHandler<E extends BaseEnum> extends BaseTypeHandler<E> {
private Class<E> type;
private E[] enums;
//设置参数到preparedStatement
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, E e, JdbcType jdbcType) throws SQLException {
if (jdbcType == null) {
preparedStatement.setObject(i, e.getKey());
} else {
preparedStatement.setObject(i, e.getKey(), jdbcType.TYPE_CODE);
}
}
//设置参数到preparedStatement
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, E e, JdbcType jdbcType) throws SQLException {
if (jdbcType == null) {
preparedStatement.setObject(i, e.getKey());
} else {
preparedStatement.setObject(i, e.getKey(), jdbcType.TYPE_CODE);
}
}
//根据ResultSet返回的key,找到其对应的enum
@Override
public E getNullableResult(ResultSet resultSet, String s) throws SQLException {
if (resultSet.wasNull()) {
return null;
}
Object key = resultSet.getObject(s);
return locateEnumsStatus(key);
}
// 省略部分方法。
/**
* @param key
* @return
*/
private E locateEnumsStatus(Object key) {
if (key instanceof Integer) {
for (E anEnum : enums) {
if (anEnum.getKey() == key) {
return anEnum;
}
}
throw new IllegalArgumentException("未知的枚举类型:" + key + ",请核对" + type.getSimpleName());
}
if (key instanceof String) {
for (E anEnum : enums) {
if (anEnum.getKey().equals(key)) {
return anEnum;
}
}
throw new IllegalArgumentException("未知的枚举类型:" + key + ",请核对" + type.getSimpleName());
}
throw new IllegalArgumentException("未知的枚举类型:" + key + ",请核对" + type.getSimpleName());
}
}
如上处理后,我们就可以在配置文件或者映射文件中配置使用通用的处理器了。
我们只需要在配置文件中配置(1-1配置)
。。。。。。。。。。。。。。。。。
版权原因,完整文章,请参考如下: