ssm框架下枚举类的转换是分为两个问题:一,前台页面传输的数据json和Java对象的转换,即String转enum;二,数据库的数据data和Java对象的转换。
前台页面传输的数据
enum枚举类实例
import org.codehaus.jackson.annotate.JsonValue;
/**
* Y/N
*
* @author duan
*
*/
public enum SYSSET {
Y("是", 1), N("否", 0);
private String value;
private int index;
private SYSSET(String value, int index) {
this.value = value;
this.index = index;
}
public static SYSSET get(String value) {
for (SYSSET p : SYSSET.values()) {
if (p.getValue().equals(value)) {
return p;
}
}
return null;
}
public static SYSSET get(int index) {
for (SYSSET p : SYSSET.values()) {
if (p.getIndex() == index) {
return p;
}
}
return null;
}
@JsonValue
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
这里我在getValue()方法上加了属性@JsonValue,用于返回值返回前台时,将枚举类SYSSET返回对应的value里的String(“是"或者"否”)
Converter转换类
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
/**
* 通用枚举转换类
* <P>
* 前台转后台<br>
* String转enum<br>
*
* @author duan
*
*/
public class ValuedEnumConverter implements ConverterFactory<String, Enum> {
@Override
public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
return new StringToEnum<T>(targetType);
}
private class StringToEnum<T extends Enum> implements Converter<String, T> {
private final Class<T> enumType;
public StringToEnum(Class<T> enumType) {
this.enumType = enumType;
}
@Override
public T convert(String source) {
if (source.isEmpty()) {
return null;
}
//获取枚举对应的常量
Object[] objects = enumType.getEnumConstants();
Method getValue;
try {
//获取枚举对应的getValue方法
getValue = enumType.getMethod("getValue");
for (Object obj : objects) {
/**
* Object java.lang.reflect.Method.invoke(Object obj, Object... args)
* throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
* Parameters:
* obj the object the underlying method is invoked from
* args the arguments used for the method call
* Returns:
* the result of dispatching the method represented bythis object on obj with parameters args
*/
//invoke(调用)就是调用Method类代表的方法。可以实现动态调用,例如可以动态的传人参数,可以把方法参数化。
if (getValue.invoke(obj).equals(source)) {
return (T) obj;
}
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
}
Spring的xml配置
<!-- 枚举对象转换 -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.caijai.base.web.ValuedEnumConverter" />
</set>
</property>
</bean>
<mvc:annotation-driven conversion-service="conversionService">
</mvc:annotation-driven>
同样的其他的类型的转换也可以自定义Converter进行操作
eg:时间类型的转换
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MuDateConverter implements Converter<String, Date> {
@Override
public Date convert(String value) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date=null;
try {
date = simpleDateFormat.parse(value);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
mybatis的枚举类型数据传输
类实例
import com...SYSSET;
public class User {
private String code;
private String name;
private SYSSET isState;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public SYSSET getIsState() {
return isState;
}
public void setIsState(SYSSET isState) {
this.isState = isState;
}
}
mapper.XML的属性对应
<resultMap type="com...SysUser" id="userSql">
<result column="code" property="code" />
<result column="name" property="name" />
<result column="isState" property="isState" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>
</resultMap>
EnumTypeHandler直接存储name值。它是mybatis默认的枚举类型转换器。
EnumOrdinalTypeHandler存储enum类里的序号值,此时数据库表字段一般对应用smallint/int类型的处理。
一般情况下想存储的并不是枚举的顺序号,而是存储自定义的id值,这时我们就需要自己写enum的处理类。
BaseTypeHandler转换类
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
/**
* 通用枚举转换类
* <P>
* 前台转后台<br>
* String转enum<br>
*
* @author duan
*
*/
public class ValuedEnumHandler<T extends Enum> extends BaseTypeHandler<T> {
private final Class<T> enumType;
public ValuedEnumHandler(Class<T> enumType) {
this.enumType = enumType;
}
@Override
public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
// 根据数据库存储类型决定获取类型,本例子中数据库中存放数值类型
/**
* columnName是int的时候,
* columnName列为Null,用rs.getInt读出来的值为0,但是rs.wasNull()==true
* columnName列为0,用rs.getInt读出来的值也为0.但是rs.wasNull()==false
*/
int i = rs.getInt(columnName);
if (rs.wasNull()) {
return null;
} else {
//获取枚举对应的常量
Object[] objects = enumType.getEnumConstants();
Method getIndex;
try {
//获取枚举对应的getValue方法
getIndex = enumType.getMethod("getIndex");
for (Object obj : objects) {
/**
* Object java.lang.reflect.Method.invoke(Object obj, Object... args)
* throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
* Parameters:
* obj the object the underlying method is invoked from
* args the arguments used for the method call
* Returns:
* the result of dispatching the method represented bythis object on obj with parameters args
*/
//invoke(调用)就是调用Method类代表的方法。可以实现动态调用,例如可以动态的传人参数,可以把方法参数化。
if (getIndex.invoke(obj).equals(i)) {
return (T) obj;
}
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
// TODO Auto-generated method stub
return null;
}
}
对应的mapper.XML
<resultMap type="com...SysUser" id="userSql">
<result column="code" property="code" />
<result column="name" property="name" />
<result column="isState" property="isState" typeHandler="com...ValuedEnumHandler"/>
</resultMap>
同样的其他的类型的转换也可以自定义BaseTypeHandler进行操作
eg:时间类型的转换
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
/**
* Title: DateHandler<p>
* Description: <br>
* @author duan
* @date 2018年11月21日
*/
public class DateHandler extends BaseTypeHandler<String> {
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
Object value = rs.getObject(columnName);
if (value == null) {
return null;
}
if (value instanceof Timestamp) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(value);
}
return value+"";
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
throws SQLException {
// TODO Auto-generated method stub
}
@Override
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
// TODO Auto-generated method stub
return null;
}
}
参考资料:
springMVC 枚举参数转换
通用枚举类型处理(一)
【MyBatis学习17】用typeHandlers处理enum类型