mybatis中使用枚举类做增删改,直接映射返回Vo对象,传递枚举在xml中

在系统中,有些类型、状态等特别多,代码中写了很多的逻辑判断。本文将枚举类和普通java数据类型的字段一样在mybatise中直接操作存入修改和查询返回,并且以整个项目考虑,适用于项目中存在大量的枚举类情形,不要觉得复杂内容长,不就是粘贴复制吗?超级简单好吧!如下xml中是对一个表的基本操作:

mybatis中使用枚举类做增删改,直接映射返回Vo对象,传递枚举在xml中_第1张图片

下面是含有枚举类属性的普通java类

public class ContractSignatureEntity extends BaseEntity {

    /**
     * 电子合同模板配置ID
     */
    private Integer contractTemplateId;
    /**
     * 电子合同签署状态
     */
    private SignatureStatus signatureStatus;

get。。set..

}

一个普通的枚举类

public enum SignatureStatus implements EnumShow {
    SIGN_CANCEL(-1, "已撤销", "已撤销"),
    SIGN_ARCHIVED_FAILED(-7, "签署中", "归档失败"),
    SIGN_ARCHIVED_SUCCESS(7, "已归档", "已归档");

    private int value;
    private String desc;
    private String flowDesc;

    SignatureStatus(int value, String desc, String flowDesc) {
        this.value = value;
        this.desc = desc;
        this.flowDesc = flowDesc;
    }

    public static SignatureStatus forValue(int value) {
        for (SignatureStatus signatureStatus : SignatureStatus.values()) {
            if (signatureStatus.value == value) {
                return signatureStatus;
            }
        }
        return null;
    }

    /**
     * 生成合同状态位
     *
     * @return
     */
    public static List getCanGenerateStatus() {
        return Arrays.asList(INIT, SIGN_CANCEL);
    }

    /**
     * 落公司章状态位
     *
     * @return
     */
    public static List getCanCompanySignStatus() {
        return Arrays.asList(SIGN_PROCESSED_USER_SUCCESS, SIGN_PROCESSED_COM_FAILED);
    } 

    @Override
    public String getName() {
        return name();
    }

    @Override
    public int getValue() {
        return value;
    }

    @Override
    public String getDesc() {
        return desc;
    }

    public String getFlowDesc() {
        return flowDesc;
    }
}

EnumShow 提供给前端用的枚举名称,重写了枚举getName,如果前端不需要可以直接实现EnumBehaviour接口

public interface EnumShow extends EnumBehaviour {

    String getName();
}

我们有两个枚举类需要实现的接口,EnumBehaviour(int类型)和EnumStringBehaviour(varchar类型),本文示例是int类型的状态存到数据库,所以只需要枚举类实现EnumBehaviour接口即可。其实这样做只是将重写了相应方法的公共部分抽离出来,以便项目中的所有枚举类使用。

public interface EnumBehaviour {

    int getValue();

    String getDesc();
}
public interface EnumStringBehaviour {

    String getValue();

    String getDesc();
}
下面是关于自动与DB映射转换的两个类,将至直接复制到项目中,按照后面的配置配置就可以了

DB保存int类型的

public class EnumValueTypeHandler extends BaseTypeHandler {

    private Class type;
    private final EnumBehaviour[] enums;

    /**
     * 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现
     *
     * @param type 配置文件中设置的转换类
     */
    public EnumValueTypeHandler(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.");
    }

    @Override
    public EnumBehaviour getNullableResult(ResultSet rs, String columnName) throws SQLException {
        // 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型
        int i = rs.getInt(columnName);
        if (rs.wasNull()) {
            return null;
        } else {
            // 根据数据库中的code值,定位EnumBehaviour子类
            return locateEnumBehaviour(i);
        }
    }

    @Override
    public EnumBehaviour getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        // 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型
        int i = rs.getInt(columnIndex);
        if (rs.wasNull()) {
            return null;
        } else {
            // 根据数据库中的code值,定位EnumBehaviour子类
            return locateEnumBehaviour(i);
        }
    }

    @Override
    public EnumBehaviour getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        // 根据数据库存储类型决定获取类型,本例子中数据库中存放INT类型
        int i = cs.getInt(columnIndex);
        if (cs.wasNull()) {
            return null;
        } else {
            // 根据数据库中的code值,定位EnumBehaviour子类
            return locateEnumBehaviour(i);
        }
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, EnumBehaviour parameter, JdbcType jdbcType)
            throws SQLException {
        // baseTypeHandler已经帮我们做了parameter的null判断
        ps.setInt(i, parameter.getValue());
    }

    /**
     * 枚举类型转换,由于构造函数获取了枚举的子类enums,让遍历更加高效快捷
     *
     * @param code 数据库中存储的自定义code属性
     * @return code对应的枚举类
     */
    private EnumBehaviour locateEnumBehaviour(int code) {
        for (EnumBehaviour status : enums) {
            if (status.getValue() == code) {
                return status;
            }
        }
        throw new IllegalArgumentException("未知的枚举类型:" + code + ",请核对" + type.getSimpleName());
    }
}

DB保存varchar类型的

public class EnumStringValueTypeHandler extends BaseTypeHandler {

    private Class type;
    private final EnumStringBehaviour[] enums;

    /**
     * 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现
     *
     * @param type 配置文件中设置的转换类
     */
    public EnumStringValueTypeHandler(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.");
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, EnumStringBehaviour parameter, JdbcType jdbcType) throws SQLException {
        // baseTypeHandler已经帮我们做了parameter的null判断
        ps.setString(i, parameter.getValue());
    }

    @Override
    public EnumStringBehaviour getNullableResult(ResultSet rs, String columnName) throws SQLException {
        // 根据数据库存储类型决定获取类型,本例子中数据库中存放VARCHAR类型
        String str = rs.getString(columnName);
        if (rs.wasNull()) {
            return null;
        } else {
            // 根据数据库中的code值,定位EnumBehaviour子类
            return locateStringEnumBehaviour(str);
        }
    }

    @Override
    public EnumStringBehaviour getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        // 根据数据库存储类型决定获取类型,本例子中数据库中存放VARCHAR类型
        String str = rs.getString(columnIndex);
        if (rs.wasNull()) {
            return null;
        } else {
            // 根据数据库中的code值,定位EnumBehaviour子类
            return locateStringEnumBehaviour(str);
        }
    }

    @Override
    public EnumStringBehaviour getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        // 根据数据库存储类型决定获取类型,本例子中数据库中存放VARCHAR类型
        String str = cs.getString(columnIndex);
        if (cs.wasNull()) {
            return null;
        } else {
            // 根据数据库中的code值,定位EnumBehaviour子类
            return locateStringEnumBehaviour(str);
        }
    }

    /**
     * 枚举类型转换,由于构造函数获取了枚举的子类enums,让遍历更加高效快捷
     *
     * @param code 数据库中存储的自定义code属性
     * @return code对应的枚举类
     */
    private EnumStringBehaviour locateStringEnumBehaviour(String code) {
        for (EnumStringBehaviour enumStringBehaviour : enums) {
            if (enumStringBehaviour.getValue().compareTo(code) == 0) {
                return enumStringBehaviour;
            }
        }
        throw new IllegalArgumentException("未知的枚举类型:" + code + ",请核对" + type.getSimpleName());
    }
}

下面是一个配置信息的xml,名字随便起,该xml配置了枚举类和想要映射到数据库的类型类的关系,一个int,一个varchar,也就是说你得告诉数据库你这个枚举放入数据库的值是啥吧?mybatis-config.xml




    
        
    
    

        
    

最后就是配置启动项了,你写了xml不得让项目去自己扫描使用吗?下面以springBoot为例:

在MybatisConfiguration类的下的sqlSessionFactoryBean中加入:bean.setConfigLocation(resolver.getResource("classpath:mybatis-config.xml"));然后就OK了,可以完美的使用了。

在sqlSessionFactory里加入xml地址就行,可以和我一样在java类里写也可以直接在配置文件中写都行。

你可能感兴趣的:(mybatis)