BaseEnums封装和数据库类型自动转换

2020-08-12  本文已影响0人  prope
/**
 * 枚举类的统一处理
 * @author wanter
 *
 * @param <T> 自己的类型
 */
public interface BaseEnums<T> {

    /**
     * 获取编码
     *
     * @return
     */
    Integer getCode();

    /**
     * 获取名称
     *
     * @return
     */
    String getName();

}

2:编写EnumUtil工具库类

/**
 * 枚举处理工具类
 *
 * @author xxx
 * @date 2020年08月12日18:19:23
 */
public class EnumUtil {
    /**
     * 根据code获取枚举
     *
     * @param enumClass
     * @param code
     * @param <E>
     * @return
     */
    public static <E extends Enum<?> & BaseEnums> E codeOf(Class<E> enumClass, int code) {
        E[] enumConstants = enumClass.getEnumConstants();
        for (E e : enumConstants) {
            if (e.getCode() == code) {
                return e;
            }
        }
        return null;
    }

    /**
     * 根据msg获取枚举
     *
     * @param enumClass
     * @param name
     * @param <E>
     * @return
     */
    public static <E extends Enum<?> & BaseEnums> E nameOf(Class<E> enumClass, String name) {
        E[] enumConstants = enumClass.getEnumConstants();
        for (E e : enumConstants) {
            if (e.getName().equals(name)) {
                return e;
            }
        }
        return null;
    }
}

3:编写mybatis的类型处理器(mybatis如何转换BaseEnums类型数据)

/**
 * 对枚举和数据库表之间的翻译
 *
 * @author xxx
 * @date 2020年08月12日18:22:28
 */
public class CommonEnumsHandler<E extends Enum<?> & BaseEnums> extends BaseTypeHandler<BaseEnums> {
    private Class<E> type;

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

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, BaseEnums parameter, JdbcType jdbcType) throws SQLException {
        ps.setInt(i, parameter.getCode());
    }

    @Override
    public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
        int i = rs.getInt(columnName);

        if (rs.wasNull()) {
            return null;
        } else {
            return locateEnumStatus(i);
        }
    }

    @Override
    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        int i = rs.getInt(columnIndex);
        if (rs.wasNull()) {
            return null;
        } else {
            return locateEnumStatus(i);
        }
    }

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

    /**
     * 枚举类型转换,由于构造函数获取了枚举的子类enums,让遍历更加高效快捷
     *
     * @param code 数据库中存储的自定义code属性
     * @return code对应的枚举类
     */
    private E locateEnumStatus(Integer code) {
        return EnumUtil.codeOf(type, code);
    }

/**
 * <p>
 * 设置数据是否有效
 *
 * @author xxx
 * @version 1.0
 * @since 2019年10月12日17:39:32
 */
public enum DeleteEnum implements BaseEnums<DeleteEnum> {
    // 删除
    DELETE_YES(0, "无效"),
    //不删除
    DELETE_NO(1, "有效");

    private Integer code;

    private String name;

    DeleteEnum(Integer code, String name) {
        this.code = code;
        this.name = name;
    }

    @Override
    public Integer getCode() {
        return code;
    }

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

2:在其他实体类中使用该字段

/**
 * @author xxx
 * @version 1.0
 * @since 2020年08月12日18:32:39
 */
public class CapitalDebt extends BaseEntity<CapitalDebt> {

    private Long id;
    private String uuid;
    /**
     * 是否删除 0=删除 1=有效
     */
    private DeleteEnum deleteFlag;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUuid() {
        return uuid;
    }

    public void setUuid(String uuid) {
        this.uuid = uuid;
    }

    public DeleteEnum getDeleteFlag() {
        return deleteFlag;
    }

    public void setDeleteFlag(DeleteEnum deleteFlag) {
        this.deleteFlag = deleteFlag;
    }

    @Override
    public String toString() {
        return "CapitalDebt{" +
                "id=" + id +
                ", uuid='" + uuid + '\'' +
                ", deleteFlag=" + deleteFlag +
                '}';
    }
}

3:编写xml

<!-- resultMap 中的定义 -->
    <resultMap type="com.xxx.xxxx" id="xxxMap">
        <result property="id" column="ID"/>
        <result property="uuid" column="UUID"/>
        <result property="deleteFlag" column="delete_flag" typeHandler="com.xxx.CommonEnumsHandler"/>
    </resultMap>
<!-- 取出实体类中值处理 -->
    <sql id="entity_properties">
        #{id},
        #{uuid},
        #{deleteFlag ,typeHandler=com.xxx.CommonEnumsHandler}
    </sql>

4:升级使用
如果在系统中所有的枚举BaseEnums的情况下,如果每个xml都这么编写,则维护成本太高,有没有什么办法让mybatis知道凡是遇到BaseEnums这种类型都调用CommonEnumsHandler这个处理器来处理这个类型。答案是可以的吗?

肯定是可以的,mybatis内置了很多处理器来帮我们处理常见的数据类型,比如 BaseTypeHandler的实现类
所以只需要“告诉”mybatis,讲BaseEnums和CommonEnumsHandler全局绑定起来就可以。
**
 * 设置xml文件的扫描位置和
 * mapper对应的接口的扫描位置
 *
 * @author xxx
 * @version 2020年08月12日18:49:18
 */
@Configuration
@MapperScan({"com.*.*.*.mapper"})
public class MyBatisConfig {
    @Resource
    private DataSource dataSource;

    private final static String MAPPER_LOCATION = "classpath:/mapper/**.xml";

    /**
     * 设置xml扫描的位置
     * 设置开启驼峰转大写的开关
     *
     * @return SqlSessionFactory
     * @throws Exception
     */
    @Bean
    public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);

        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        //自动使用驼峰命名属性映射字段
        configuration.setMapUnderscoreToCamelCase(true);
//        configuration.setDefaultEnumTypeHandler(CommonEnumsHandler.class);
        //讲typeHander 默认注入到mybatis中
        TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
        typeHandlerRegistry.register(BaseEnums.class, CommonEnumsHandler.class);
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setMapperLocations(resolver.getResources(MAPPER_LOCATION));
        sqlSessionFactoryBean.setConfiguration(configuration);
        return sqlSessionFactoryBean.getObject();
    }
   
}

其中代码在项目启动的时候自动带入到全局解析中

typeHandlerRegistry.register(BaseEnums.class, CommonEnumsHandler.class);

本文完

Enum类型,mybatis类型映射,spring boot枚举优雅处理。typeHandler处理枚举

上一篇下一篇

猜你喜欢

热点阅读