MyBatis自带的EnumTypeHandler转换为文字保存在数据库,EnumOrdinalTypeHandler使用的是序号,它们的一致性都可能被轻易地破坏,所以最好的办法是自定义一个int类型
自定义公共父接口
package com.tenmao.utils.mybatis;
import java.util.Arrays;
import java.util.Optional;
public interface CodedEnum {
int getCode();
static <E extends Enum<?> & CodedEnum> Optional<E> codeOf(Class<E> enumClass, int code) {
return Arrays.stream(enumClass.getEnumConstants()).filter(e -> e.getCode() == code).findAny();
}
}
Enum的转换工具类
package com.tenmao.utils.mybatis.handler;
import com.tenmao.utils.mybatis.CodedEnum;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;
import java.sql.*;
import java.util.Optional;
@MappedTypes({CodedEnum.class})
public class CodedEnumTypeHandler<E extends Enum<?> & CodedEnum> implements TypeHandler<E> {
private Class<E> type;
public CodedEnumTypeHandler(Class<E> type) {
if (type == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.type = type;
}
@Override
public void setParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
if (parameter == null) {
ps.setNull(i, Types.TINYINT);
} else {
ps.setInt(i, parameter.getCode());
}
}
@Override
public E getResult(ResultSet rs, String columnName) throws SQLException {
int columnValue = rs.getInt(columnName);
return rs.wasNull() ? null : enumOf(columnValue);
}
@Override
public E getResult(ResultSet rs, int columnIndex) throws SQLException {
int columnValue = rs.getInt(columnIndex);
return rs.wasNull() ? null : enumOf(columnValue);
}
@Override
public E getResult(CallableStatement cs, int columnIndex) throws SQLException {
int columnValue = cs.getInt(columnIndex);
return cs.wasNull() ? null : enumOf(columnValue);
}
private E enumOf(int code) {
final Optional<E> codedEnumOpt = CodedEnum.codeOf(type, code);
if (codedEnumOpt.isPresent()) {
return codedEnumOpt.get();
} else {
throw new IllegalArgumentException("Cannot convert " + code + " to " + type.getSimpleName() + " by code value.");
}
}
}
配置使用转换工具类
data-applicationContext.xml
<bean id="data-sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="mapperLocations">
<list>
<value>classpath*:mapper/*Mapper.xml</value>
</list>
</property>
<property name="dataSource" ref="data-datasource" />
<property name="configuration" ref="mybatisConfig" />
<property name="typeHandlersPackage" value="com.tenmao.utils.mybatis.handler" />
</bean>
自定义枚举
package com.tenmao.utils.model;
import com.tenmao.utils.mybatis.CodedEnum;
public enum Weekday implements CodedEnum {
MONDAY(1),
TUESDAY(2),
WEDNESDAY(3),
THURSDAY(4),
FRIDAY(5),
SATURDAY(6),
SUNDAY(7)
private final int code;
Weekday (int code) {
this.code = code;
}
@Override
public int getCode() {
return code;
}
}
ps: 参考资料写得特别好,我之所以重新写了一下,是资料写得有点啰嗦,比如子类的注册,其实都是自动的,不需要再额外配置
自定义枚举系列
参考
作者:十毛tenmao
链接:https://www.jianshu.com/p/c84549e0ee10
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END