基于SpringBoot自定义实现Mybatis-TypeHandler

需求:
在程序中使用枚举(enum) 来表示一些状态或选项,而在数据库中使用数字来存储。这样做的好处是在程序中使用enum更直观的可以知道每个值代表的状态及含义。

分析:
EnumTypeHandler与EnumOrdinalTypeHandler是已经有的两类TypeHandler

两者之间的区别:
EnumTypeHandler存入数据库的是枚举的name,EnumOrdinalTypeHandler存入数据库的是枚举的位置。

例子:

public enum  sexEnum implements DemoEnum {

   WOMAN(0),MAN(1);
   private int code;
   private sexEnum(int code){
       this.code =code;
   }
    @Override
    public int getValue() {
        return code;
    }
}

EnumTypeHandler转换获取到的是 WOMAN OR MAN

EnumOrdinalTypeHandler获取到的是 0 OR 1(并非我们上面代码性别枚举中WOMAN()中的数字,只是位置)

因为我们需要自定义一个TypeHandler:

话不多说直接上代码:

1、定义一个接口,作用是在从数据库中获取到值时可以转换

public interface DemoEnum {
    int getValue();
}

2、自定义基于BaseTypeHandler的公共类,目的是当你有多个枚举类时解耦,其中的get方法是上一步定义接口的作用:

public class testTypeHandler & DemoEnum> extends BaseTypeHandler {

    private Class type;
    private final E[] enums;
    public testTypeHandler(Class type) {
        if (type == null) {
            throw new IllegalArgumentException("Type argument cannot be null");
        }
        this.type = type;
        this.enums = type.getEnumConstants();
        if (this.enums == null) {
            throw new IllegalArgumentException(type.getSimpleName() + " does not represent an enum type.");
        }
    }

    public E get(int code) {
        try {
            for(E e:enums) {
                if(e.getValue() == code) {
                    return e;
                }
            }
        } catch (Exception e) {
            throw new IllegalArgumentException("erro value!");
        }
        return null;
    }
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
        ps.setInt(i,parameter.getValue());
    }
    @Override
    public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
        int value = rs.getInt(columnName);
        if (rs.wasNull()) {
            return null;
        }else {
            return get(value);
        }
    }
    @Override
    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        int value = rs.getInt(columnIndex);
        if (rs.wasNull()) {
            return null;
        }else {
            return get(value);
        }

    }
    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        int value = cs.getInt(columnIndex);
        if (cs.wasNull()) {
            return null;
        }else {
            return get(value);
        }

    }


}

3、新建一个基于上一步基类的公用类,如果你有多个枚举属性需要转换,你可以在MappedTypes注解中增加你的枚举类,目的是不用每次实现一个TypeHandler:

@MappedTypes({sexEnum.class})
public class EnumTypeHandler & DemoEnum> extends testTypeHandler {
    public EnumTypeHandler(Class type) {
        super(type);
    }
}

4、application.properties中配置

mybatis.type-handlers-package= 你的公共类的包路径

 

 

总结:写得可能有点粗糙,希望和大家一起交流。

你可能感兴趣的:(java,springboot)