zoukankan      html  css  js  c++  java
  • mybatis枚举自动转换(通用转换处理器实现)

    https://blog.csdn.net/fighterandknight/article/details/51520595

    https://blog.csdn.net/fighterandknight/article/details/51599116

    https://blog.csdn.net/fighterandknight/article/details/51600997

    版权声明:本文为Fighter168原创文章,未经允许不得转载。 https://blog.csdn.net/fighterandknight/article/details/51520595
    前言
             在上一篇博客,mybatis枚举自动转换实现,已经介绍自动转换的实现步骤,并通过例子告诉大家如何实现枚举的自动转换了。 那么在博客的最后想到,定义一个万能的枚举转换处理器,具体怎么实现呢,相信大神们也应该有思路了,使用泛型实现,没错,就是使用泛型实现,具体请看下面例子。

    mybatis万能枚举转换处理器
    定义枚举接口
    为什么要定义枚举的接口呢,定义接口的好处,其实主要目的是为了在万能枚举转换器中方便泛型的使用,而且还可以规范枚举类的实现。
    package net.itaem.less;

    /**
    * @author: Fighter168
    */
    public interface BaseEnum<E extends Enum<?>, T> {
    public T getValue();
    public String getDisplayName();
    }


    实现枚举接口,定义枚举
    实现BaseEnum接口,定义PersonType枚举
    package net.itaem.less;

    import java.util.HashMap;
    import java.util.Map;

    /**
    * @author: Fighter168
    */
    public enum PersonType implements BaseEnum<PersonType, String>{
    student("1","学生"),
    teacher("2","教师");

    private String value;
    private String displayName;

    static Map<String,PersonType> enumMap=new HashMap<String, PersonType>();
    static{
    for(PersonType type:PersonType.values()){
    enumMap.put(type.getValue(), type);
    }
    }

    private PersonType(String value,String displayName) {
    this.value=value;
    this.displayName=displayName;
    }

    public String getValue() {
    return value;
    }
    public void setValue(String value) {
    this.value = value;
    }
    public String getDisplayName() {
    return displayName;
    }
    public void setDisplayName(String displayName) {
    this.displayName = displayName;
    }

    public static PersonType getEnum(String value) {
    return enumMap.get(value);
    }
    }


    定义万能枚举转换处理器
    package net.itaem.handler;

    import java.sql.CallableStatement;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;

    import net.itaem.less.BaseEnum;

    import org.apache.ibatis.type.BaseTypeHandler;
    import org.apache.ibatis.type.JdbcType;

    /**
    * @author: Fighter168
    */
    public final class UniversalEnumHandler<E extends BaseEnum> extends BaseTypeHandler<E> {

    private Class<E> type;
    private E [] enums;

    /**
    * 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现
    * @param type 配置文件中设置的转换类
    */
    public UniversalEnumHandler(Class<E> 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, E parameter,
    JdbcType jdbcType) throws SQLException {
    //BaseTypeHandler已经帮我们做了parameter的null判断
    ps.setObject(i,(String)parameter.getValue(), jdbcType.TYPE_CODE);
    }

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

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

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

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

    测试
               接下来,我们就修改原来的例子(上一篇博客的例子:mybatis枚举自动转换实现),只需修改typeHandler,修改成
    <typeHandler handler="net.itaem.handler.UniversalHandler"
    javaType="net.itaem.less.PersonType" jdbcType="CHAR"/>
    然后我们再次运行测试用例,会发现,我们的查询得到的结果还是一样,这样,我们就不需要为每一个枚举创建一个Handler去自动转换数据库中的枚举了。


    自动扫描枚举注册想法
                 做到这里,或许我们又想了,要是我们一个项目特别大,有几十个甚至是上百个枚举呢,那怎么办,难道我要一个个在typeHandler里面去加,加一百几十行?!个人觉得非常麻烦,影响我们的开发速度,so,能不能实现我们想要的像扫描下枚举的所在的包目录就可以注册的枚举做自动转换呢?具体怎么实现?下篇博客我会教大家如何实现。

    ---------------------
    作者:Fighter168
    来源:CSDN
    原文:https://blog.csdn.net/fighterandknight/article/details/51520595
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    案例19-页面使用ajax显示类别菜单
    案例18-首页最新商品和热门商品显示
    案例17-validate自定义校验规则校验验证码是否输入正确
    案例16-validate自定义校验规则校验用户名是否存在
    案例15-基本的表单校验使用validate
    测开之路六十九:监控平台之视图层
    测开之路六十八:监控平台之监控逻辑和处理逻辑
    测开之路六十七:监控平台之附加功能准备
    测开之路六十六:UI测试平台之处理逻辑和蓝图添加到程序入口
    测开之路六十五:UI测试平台之js
  • 原文地址:https://www.cnblogs.com/yuluoxingkong/p/10196293.html
Copyright © 2011-2022 走看看