mybatis入门与精通-TypeHandler详解

mybatis为我们定义了很多自定义的Handler,以enum这种特殊类型来讲解下如何使用,其他类型的类似处理即可。

EnumTypeHandler

mybatis默认处理enum的Handler,将enum的属性名映射到数据库中,处理为字符串。

如果没有配置typeHandler,遇到enum类型的属性就会用EnumTypeHandler处理,要用其他的需要配置:

<configuration>
    <typeHandlers>
        <typeHandler handler="com.demo.test.service.impl.dao.handler.IdEnumHandler"
                     javaType="com.demo.test.service.type.Module" />
    </typeHandlers>
</configuration>
  • 值得注意的是,这里如果配置了jdbcType,preperStatement时就不会生效了,还是会采用EnumTypeHandler处理。(原因暂时没有深究)

EnumOrdinalTypeHandler

mybatis提供的另一个处理enum的Handler,将enum的定义顺序下标映射到数据库中,处理为整型。

自定义EnumHandler

我们也可以继承BaseTypeHandler实现自己的Handler,

自定义通用EnumHandler

首先定义一个接口,让所有要使用这个Handler的enum都实现这个接口。

public interface IdEnum {
    Integer getId();
}

然后可以自定义Handler,主要思路来源于EnumOrdinalTypeHandler,只是他是根据enum的顺序获得,而我们要定义为根据某个特殊字段获得,所以将他的enum数组改成Map方便处理。看下他的源码:

public class EnumOrdinalTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> {

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

  public EnumOrdinalTypeHandler(Class<E> type) {
    if (type == null) throw new IllegalArgumentException("Type argument cannot be null");
    this.type = type;
    /*这行代码是注入数组,我们改为Map,再根据需求确定key*/
    this.enums = type.getEnumConstants();
    if (this.enums == null) throw new IllegalArgumentException(type.getSimpleName() + " does not represent an enum type.");
  }
}

自定义通用Handler代码如下:

public class IdEnumHandler<E extends Enum<E>> extends BaseTypeHandler<E> {
    private Class<E> type;
    private Map<Integer, E> map = new HashMap<Integer,E>();
    public IdEnumHandler(Class<E> type) {
        if (type == null) {
            throw new IllegalArgumentException("Type argument cannot be null");
        }
        this.type = type;
        E[] enums = type.getEnumConstants();
        if (enums == null) {
            throw new IllegalArgumentException(type.getSimpleName() + " does not represent an enum type.");
        }
        for (E e : enums) {
            IdEnum idEnum = (IdEnum) e;
            map.put(idEnum.getId(), e);
        }
    }
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
        IdEnum idEnum = (IdEnum) parameter;
        ps.setInt(i, idEnum.getId());
    }
    @Override
    public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
        int i = rs.getInt(columnName);
        if (rs.wasNull()) {
            return null;
        } else {
            return getIdEnum(i);
        }
    }
    @Override
    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        int i = rs.getInt(columnIndex);
        if (rs.wasNull()) {
            return null;
        } else {
            return getIdEnum(i);
        }
    }
    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        int i = cs.getInt(columnIndex);
        if (cs.wasNull()) {
            return null;
        } else {
            return getIdEnum(i);
        }
    }
    private E getIdEnum(int id) {
        try {
            return map.get(id);
        } catch (Exception ex) {
            throw new IllegalArgumentException(
                    "Cannot convert " + id + " to " + type.getSimpleName() + " by value.", ex);
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,607评论 0 4
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,269评论 25 708
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,923评论 18 139
  • 群里有位抑郁症患者,有十年的病史,是个记者,说自己所接触过的心理医生大部分都是自己有很多心理问题的,却治愈不...
    竞二阅读 838评论 6 5
  • 昨天是女生独立日,晚上与这三位巨匠去江湖酒吧,听大瓦哥最最最喜欢的女神刘润洁唱情歌,请看此图! 人的一生,就是一场...
    北京盛艺阁文化传媒阅读 176评论 0 0