枚举相对来说,是很常见的一种使用类型,但是在实际项目中,使用更加广泛,在很多场景,页面使用的是汉字,而数据库存储的却是数字,java程序运行时传输的便是枚举,这就涉及到了数据的展示,传输,存储
示例:项目使用的是微服务(spring could),单体子应用为spring boot + mybatis ,数据库使用mysql
①.页面给用户展示的时候,自然是汉字,也就是描述,如图
②.java程序所接收与传输的类型便是枚举,如图(注:@ApiModelProperty注解为项目中使用springfox-swagger2,与本文介绍无关)
③.枚举类,如图
④.数据库字段类型为TINYINT,如图
以上①②③④已介绍各个环节的示例图,在我们java程序中使用的是OrgTypeEnum枚举类型作为传输类型,在页面,给用户展示的是枚举中的description字段值,而我的数据库中存储的是枚举类中的code字段值,这就牵扯到类型转换
实际开发过程:
一:页面JS发起的ajax请求枚举字段值直接使用枚举值(大写字母),例如:机构类型为总公司,则字段传输时直接赋值为 {"orgType": "HEADQUARTERS"}
二:java程序Controller层用实体对象接收,注意@RequestBody注解别忘了写,如图所示
三:该项目为mysql与mybatis,故涉及到mybatis转换器,(转换器显现原理在此文章中先不介绍,请自行查阅资料)
四:XML文件中,如果涉及到枚举类型的表单XML,则无法使用自动驼峰命名法,需要设置resultMap值,在基本的String或者int,long之类的类型可以不用写jdbcType,但是枚举字段,必须要写typeHandler,必须制定typeHandler为自己提供的转换器,例如:typeHandler="*.*.*.*.mybatis.handler.EnumTypeHandler" (此路径为转换器类路径)
五:页面需要知道枚举值是什么,则需要传输给页面,在项目公有返回实体中添加一个字段代表枚举值,如图
六:页面接口相应,如图
以上,则是实际项目中,枚举应用场景之一的介绍,下面贴出所有相应代码片段
public interface BaseEnum {
Integer getCode();
String getDescription();
}
public class EnumTypeHandler extends BaseTypeHandler {
private Class type;
private final BaseEnum[] enums;
/**
* 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现
* @param type 配置文件中设置的转换类
*/
public EnumTypeHandler(Class type) {
if (type == null)
throw new IllegalArgumentException("Type argument cannot be null");
this.type = type;
this.enums = type.getEnumConstants();
}
@Override
public BaseEnum getNullableResult(ResultSet rs, String columnName) throws SQLException {
// 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型
int i = rs.getInt(columnName);
if (rs.wasNull()) {
return null;
} else {
// 根据数据库中的code值,定位BaseEnum子类
return locateBaseEnum(i);
}
}
@Override
public BaseEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
// 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型
int i = rs.getInt(columnIndex);
if (rs.wasNull()) {
return null;
} else {
// 根据数据库中的code值,定位BaseEnum子类
return locateBaseEnum(i);
}
}
@Override
public BaseEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
// 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型
int i = cs.getInt(columnIndex);
if (cs.wasNull()) {
return null;
} else {
// 根据数据库中的code值,定位BaseEnum子类
return locateBaseEnum(i);
}
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, BaseEnum parameter, JdbcType jdbcType)
throws SQLException {
// baseTypeHandler已经帮我们做了parameter的null判断
ps.setInt(i, parameter.getCode());
}
/**
* 枚举类型转换,由于构造函数获取了枚举的子类enums,让遍历更加高效快捷
* @param code 数据库中存储的自定义code属性
* @return code对应的枚举类
*/
private BaseEnum locateBaseEnum(int code) {
for (BaseEnum status : enums) {
if (status.getCode().equals(Integer.valueOf(code))) {
return status;
}
}
throw new IllegalArgumentException("未知的枚举类型:" + code + ",请核对" + type.getSimpleName());
}
}
public class EnumUtil {
/**默认枚举类属性*/
private final static String[] ATTRIBUTE_NAME_ARR = {"code", "description"};
/**
* Description: [将Enum枚举转换成JSON字符串]
* @param clazz 枚举class
* @param attributeNames 枚举属性,可不填,默认枚举属性为[code,description]
* @return: java.lang.String 处理后的JSON字符串
* @version 1.0
**/
public static String getEnumJson(Class clazz, String ... attributeNames) {
if (!clazz.isEnum()) {
return null;
}
try {
String[] attributeNameArr = (attributeNames != null && attributeNames.length > 0) ? attributeNames : ATTRIBUTE_NAME_ARR;
StringBuilder jsonBud = new StringBuilder();
jsonBud.append("[");
List enumList = Arrays.asList(clazz.getEnumConstants());
int size = enumList.size();
for (int i = 0; i < size; i ++) {
jsonBud.append("{");
Object enumObj = enumList.get(i);
jsonBud.append("\"").append("enumValue").append("\":").append("\"").append(enumObj).append("\",");
int length = attributeNameArr.length;
for (int j = 0; j < length; j ++) {
String attributeName = attributeNameArr[j];
String getMethodName = "get" + caseInitials(attributeName);
Method method = clazz.getMethod(getMethodName);
boolean flag = "class java.lang.String".equals(method.getReturnType().toString());
Object obj = method.invoke(enumObj);
jsonBud.append("\"").append(attributeName).append("\":");
if (flag) {
jsonBud.append("\"").append(obj).append("\"");
} else {
jsonBud.append(obj);
}
if (j < length - 1) {
jsonBud.append(",");
}
}
jsonBud.append("}");
if (i < size - 1) {
jsonBud.append(",");
}
}
jsonBud.append("]");
return jsonBud.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Description: [首字母大写]
* @param attribute 目标字符串
* @return: java.lang.String
* @version 1.0
**/
private static String caseInitials(String attribute){
if (null == attribute) {
return null;
}
char[] cs = attribute.toCharArray();
cs[0] -= 32;
return String.valueOf(cs);
}
}
注:使用EnumUtil时,请注意枚举类的属性名,如果有变更,则请修改EnumUtil中的ATTRIBUTE_NAME_ARR属性值!
©转载请标明出处,若有疑问,请联系:[email protected]