你是不是也有这样的需求:
PENDING(4, "审核中"),
APPROVED(5, "通过"),
REJECTED(6, "未通过");
如上三个枚举值,那么数据库中该如何存枚举值类型呢?
mybatis 有两个枚举类型处理器: (默认的是2)
EnumOrdinalTypeHandler// Enum.ordinal() 存枚举的下标,如: 0EnumTypeHandler// Enum.name() 存枚举字符串,如: "PENDING"
那我如果想要存 PENDING(4, "审核中") 中的 4 为值该如何处理了?
如果你也有这样的需求,那么可以继续阅读。
自定义枚举类型处理器
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;
public class CustomEnumTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> {
private final Logger logger = LoggerFactory.getLogger(CustomEnumTypeHandler.class);
private final Class<E> type;
public CustomEnumTypeHandler(Class<E> type) {
if (type == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.type = type;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int index, E parameter, JdbcType jdbcType) throws SQLException {
try {
Method method = type.getMethod("getCode");
int code = (int) method.invoke(Enum.valueOf(type, parameter.name()));
ps.setInt(index, code);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
@Override
public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
int code = rs.getInt(columnName);
if (code == 0 && rs.wasNull()) {
return null;
}
return toCodeEnum(ordinal);
}
@Override
public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
int code = rs.getInt(columnIndex);
if (code == 0 && rs.wasNull()) {
return null;
}
return toCodeEnum(ordinal);
}
@Override
public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
int code = cs.getInt(columnIndex);
if (code == 0 && cs.wasNull()) {
return null;
}
return toCodeEnum(ordinal);
}
private E toCodeEnum(int code) {
try {
Method method = type.getMethod("getEnum", int.class);
return (E) method.invoke(type, code);
} catch (Exception ex) {
throw new IllegalArgumentException("Cannot convert " + ordinal + " to " + type.getSimpleName() + " by ordinal value.", ex);
}
}
}
枚举类代码
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.HashMap;
import java.util.Map;
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum AppointmentStatus {
PENDING(4, "审核中"),
APPROVED(5, "通过"),
REJECTED(6, "未通过");
static Map<Integer, AppointmentStatus> enumMap = new HashMap<Integer, AppointmentStatus>();
static{
for(AppointmentStatus appointmentStatus : AppointmentStatus.values()){
enumMap.put(appointmentStatus.getCode(), appointmentStatus);
}
}
private int code;
private String name;
private AppointmentStatus(int code, String name) {
this.code = code;
this.name = name;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static AppointmentStatus getEnum(int code) {
return enumMap.get(code);
}
}
@JsonFormat(shape = JsonFormat.Shape.OBJECT)当字段属性是枚举类型时, 加上这条注解即可返回枚举的全部属性。如:
appointmentStatus: {
code: 4,
name: "审核中"
}
如果不加此注解,则返回的是: appointmentStatus: "PENDING"
最后 替换默认的枚举处理类型
@Bean
public SqlSessionFactory sqlSessionFactory(DriverManagerDataSource driverManagerDataSource) throws Exception {
Resource resource[] = new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml");
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(driverManagerDataSource);
sqlSessionFactoryBean.setMapperLocations(resource);
sqlSessionFactoryBean.setPlugins(new PageInterceptor());
Class<? extends TypeHandler> customEnumTypeHandler = CustomEnumTypeHandler.class;
sqlSessionFactoryBean.setDefaultEnumTypeHandler(customEnumTypeHandler); // 替换默认的枚举处理类型
return sqlSessionFactoryBean.getObject();
}