SpringBoot中關於枚舉持久化到數據庫在Mybatis下的一個實踐

網上很多文章談到了枚舉,說起枚舉,一句話描述就是使用TypeHandler

但是如果枚舉項多了TypeHandler也不是那麼容易寫的,這裏來給大家介紹一下我自己使用大量枚舉的方案。

TL;DR:

總共分成4步

1)定義【根枚舉接口】,指定唯一標識方法(getTypeId())

2)定義【實際枚舉】,實現【根枚舉接口】

3)定義【根枚舉接口TypeHandler】,用來指定枚舉轉換方式

4)定義空的【實際枚舉TypeHandler】實現【根枚舉接口TypeHandler】,這一步主要是因爲java的泛型缺陷不得不這樣

5)PO中使用@ColumnType註解標註應當使用的typeHandler

詳細教程:

首先定義一個根枚舉接口QlEnum 

/**
 * 所有的枚舉都繼承/實現這個QlEnum
 */
public interface QlEnum {
    Integer getTypeId();
}

實現自己的枚舉TimeEnum TypeEnum :


public enum TimeEnum implements QlEnum{
    ONE_MONTH(30, "1 month"),
    TWO_MONTHS(60, "2 months"),
    THREE_MONTHS(90, "3 months"),
    ;
    private Integer typeId;
    private String label;

    TimeEnum(Integer typeId, String label) {
        this.typeId = typeId;
        this.label = label;
    }

    @Override
    public Integer getTypeId() {
        return this.typeId;
    }

    public String getLabel() {
        return label;
    }
}



public enum TypeEnum implements QlEnum {
    A(20, "A"),
    B(21, "B"),
    C(22, "C"),
    ;
    private Integer typeId;
    private String displayName;

    TypeEnum(Integer typeId, String displayName) {
        this.typeId = typeId;
        this.displayName = displayName;
    }

    @Override
    public Integer getTypeId() {
        return this.typeId;
    }

    public String getDisplayName() {
        return displayName;
    }
}

實現自己的TypeHandler:QlEnumTypeHandler

@MappedTypes({QlEnum.class})
@MappedJdbcTypes({JdbcType.INTEGER})
public class QlEnumTypeHandler<E extends QlEnum> extends BaseTypeHandler<QlEnum> {
    private Class<E> clazz;

    public QlEnumTypeHandler(Class<E> enumType) {
        if (enumType == null) {
            throw new IllegalArgumentException("Type argument cannot be null");
        }
        this.clazz = enumType;
    }

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, QlEnum windLabEnum, JdbcType jdbcType) throws SQLException {
        preparedStatement.setInt(i, windLabEnum.getTypeId());
    }

    @Override
    public QlEnum getNullableResult(ResultSet resultSet, String s) throws SQLException {
        return getByType(resultSet.getInt(s));
    }

    @Override
    public QlEnum getNullableResult(ResultSet resultSet, int i) throws SQLException {
        return getByType(resultSet.getInt(i));
    }

    @Override
    public QlEnum getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        return getByType(callableStatement.getInt(i));
    }

    private QlEnum getByType(int anInt) {
        final E[] enumConstants = clazz.getEnumConstants();
        for (QlEnum enums : enumConstants) {
            if (enums.getTypeId() == anInt) {
                return enums;
            }
        }
        return null;
    }
}

實現自己的具體枚舉Handler:TypeEnumHandler 和 TimeEnumHandler


public class TimeEnumHandler extends QlEnumTypeHandler<TimeEnum>{
    public TimeEnumHandler(Class<TimeEnum> enumType) {
        super(enumType);
    }
}


public class TypeEnumHandler extends QlEnumTypeHandler<TypeEnum>{
    public TypeEnumHandler(Class<TypeEnum> enumType) {
        super(enumType);
    }
}

在PO上使用:


@Table(name = "t_d_table")
public class DTable{
    @Id
    @KeySql(useGeneratedKeys = true)
    @Column(name = "id", insertable = false)
    private Long id;
    @ColumnType(jdbcType = JdbcType.INTEGER, typeHandler = TypeEnumHandler.class)
    private TypeEnum myType;
    @ColumnType(jdbcType = JdbcType.INTEGER, typeHandler = TimeEnumHandler.class)
    private TimeEnum myTime;

    getter & setter
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章