mybatis處理enum類型

一直用hibernate,習慣了枚舉類的使用,非常方便,現在用mybatis,發現枚舉的處理,還是需要單獨處理下。

如果想使用mybatis自帶的枚舉類處理,有2種方式,一個是EnumTypeHandler,一個是EnumOrdinalTypeHandler
2者的區別是EnumTypeHandler直接存儲name值,而EnumOrdinalTypeHandler會存儲enum類裏的序號值,此時數據庫表字段一般用int類型的處理。

使用方式比較簡單,直接在mapper文件裏的字段上,加上

typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"
typeHandler="org.apache.ibatis.type.EnumTypeHandler"

然後insert或者update的地方,字段處也加上相應的typeHandler即可。


但通常的情況下,我們並不希望用序號來標記,而希望通過自定義的id值來存儲,這時我們就需要自己寫enum的處理類。

爲了使處理類通用,我們用泛型來處理,首先定義一個接口類:

public interface IntEnum<E extends Enum<E>> {  
    int getIntValue();  
}  


然後自己的枚舉類,去實現這個接口,主要是實現getIntValue方法:

public enum TestStatusEnum implements IntEnum<TestStatusEnum> {
    FAILURE(0, "failure"), SUCCESS(1, "success");
    private int index;
    private String name;

//....get set
    private TestStatusEnum(int index, String name) {
        this.index = index;
        this.name = name;
    }

    public static String fromIndex(int index) {
        for (TestStatusEnump : TestStatusEnum.values()) {
            if (index == p.getIndex())
                return p.name;
        }
        return null;
    }

    @Override
    public int getIntValue() {
        return this.index;
    }

pojo類裏的status字段屬性,定義爲 TestStatusEnum status。

然後自定義一個hanler類:


public class IntEnumTypeHandler<E extends Enum<E> & IntEnum<E>> extends  
        BaseTypeHandler<IntEnum> {  
    private Class<IntEnum> type;  
  
    public IntEnumTypeHandler(Class<IntEnum> type) {  
        if (type == null)  
            throw new IllegalArgumentException("Type argument cannot be null");  
        this.type = type;  
    }  
  
    private IntEnum convert(int status) {  
        IntEnum[] objs = type.getEnumConstants();  
        for (IntEnum em : objs) {  
            if (em.getIntValue() == status) {  
                return em;  
            }  
        }  
        return null;  
    }  
  
    @Override  
    public IntEnum getNullableResult(ResultSet rs, String columnName)  
            throws SQLException {  
        return convert(rs.getInt(columnName));  
    }  
  
    @Override  
    public IntEnum getNullableResult(ResultSet rs, int columnIndex)  
            throws SQLException {  
        return convert(rs.getInt(columnIndex));  
    }  
  
    @Override  
    public IntEnum getNullableResult(CallableStatement cs, int columnIndex)  
            throws SQLException {  
        return convert(cs.getInt(columnIndex));  
    }  
  
    @Override  
    public void setNonNullParameter(PreparedStatement ps, int i,  
            IntEnum enumObj, JdbcType jdbcType) throws SQLException {  
        // baseTypeHandler已經幫我們做了parameter的null判斷  
        ps.setInt(i, enumObj.getIntValue());  
  
    }  
}  

在mapper文件裏,加上typehandler的定義,比如:
<result column="status" property="status"
            jdbcType="BIT" typeHandler="com.**.IntEnumTypeHandler" />
insert和update的地方,同樣加上#{condition.status,jdbcType=BIT,typeHandler=com.**.IntEnumTypeHandler}

最後測試下,insert後,表裏會存儲對應的id值,select的時候,mybatis會自動獲取name值。


另外有個問題是,當使用了enum類型後,mybatis查詢,是獲取到的enum對象。比如我們enum裏,有name屬性,我們在轉換到json的時候,想直接獲取這個name屬性

,就可以使用fastjson來轉,最新版本的json已經支持讀取enum的toString方法來序列化。

代碼:
JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
        String objJson = JSON.toJSONString(results,
                SerializerFeature.WriteDateUseDateFormat,
                SerializerFeature.WriteEnumUsingToString);
        jsonObject.put("results", objJson);



https://blog.csdn.net/china_bobo/article/details/42423809

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