聊聊Mybatis的类型转换接口TypeHandler

举报
周杰伦本人 发表于 2022/08/29 22:07:37 2022/08/29
【摘要】 聊聊Mybatis的类型转换接口TypeHandler 类型处理器接口TypeHandler 类型处理器BaseTypeHandler jdbc类型转为java类型 java类型转为jdbc类型 总结 聊聊Mybatis的类型转换接口TypeHandlermybatis可以实现jdbc类型和java类型之间的转换,具体来说有一个类型转换器的接口: 类型处理器接口TypeHandlerTyp...

聊聊Mybatis的类型转换接口TypeHandler

mybatis可以实现jdbc类型和java类型之间的转换,具体来说有一个类型转换器的接口:

类型处理器接口TypeHandler

TypeHandler接口的定义如下:

public interface TypeHandler<T> {

  void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;

 
  T getResult(ResultSet rs, String columnName) throws SQLException;

  T getResult(ResultSet rs, int columnIndex) throws SQLException;

  T getResult(CallableStatement cs, int columnIndex) throws SQLException;

}

接口中定义了设置参数的方法和获取结果的方法,根据参数不同定义了三种获取结果的方法,这是Java多态的体现,而接口的定义和方法的定义都使用了泛型。

类型处理器BaseTypeHandler

jdbc类型转为java类型

BaseTypeHandler类实现了TypeHandler接口,实现了setParameter()方法

这是BaseTypeHandler类的setParameter()方法的实现逻辑:

@Override
  public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
    if (parameter == null) {
      if (jdbcType == null) {
        throw new TypeException("JDBC requires that the JdbcType must be specified for all nullable parameters.");
      }
      try {
        ps.setNull(i, jdbcType.TYPE_CODE);
      } catch (SQLException e) {
        throw new TypeException("Error setting null for parameter #" + i + " with JdbcType " + jdbcType + " . "
              + "Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. "
              + "Cause: " + e, e);
      }
    } else {
      try {
        setNonNullParameter(ps, i, parameter, jdbcType);
      } catch (Exception e) {
        throw new TypeException("Error setting non null for parameter #" + i + " with JdbcType " + jdbcType + " . "
              + "Try setting a different JdbcType for this parameter or a different configuration property. "
              + "Cause: " + e, e);
      }
    }
  }

这个方法看着很长,其实逻辑非常的简单,方法中就是设置PreparedStatement的参数,也是参数绑定,将jdbcType转为Java类型,setNonNullParameter是抽象方法,根据不同的参数类型有不同的类实现了这个方法,比如LongTypeHandler实现的setNonNullParameter()方法:

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

java类型转为jdbc类型

BaseTypeHandler类作为TypeHandler接口的基础实现类,它同样实现了获取转换后的结果的方法。
BaseTypeHandler类的getResult()方法:

@Override
  public T getResult(CallableStatement cs, int columnIndex) throws SQLException {
    try {
      return getNullableResult(cs, columnIndex);
    } catch (Exception e) {
      throw new ResultMapException("Error attempting to get column #" + columnIndex + " from callable statement.  Cause: " + e, e);
    }
  }

方法也比较简单,直接调用了getNullableResult抽象类,功能就是从ResultSet中获取数据,把Java类型转换为JdbcType类型,比如LongTypeHandler实现的getNullableResult():

@Override
  public Long getNullableResult(ResultSet rs, String columnName)
      throws SQLException {
    long result = rs.getLong(columnName);
    return result == 0 && rs.wasNull() ? null : result;
  }

这一块的逻辑和设置参数的方法整体逻辑是差不多的,整体思想有种模板方法设计模式的设计思想

通过源码分析我们知道了TypeHandler接口的作用就是用来实现类型转换的,mybatis在初始化的时候就获取TypeHandler,然后创建TypeHandler实例注册到TypeHandlerRegistry中,由TypeHandlerRegistry来进行管理这些实例,下篇文章中我们介绍一下TypeHandlerRegistry这个类

总结

这篇文章讲了Mybatis的类型转换接口TypeHandler和它的实现类BaseTypeHandler,类型转换接口显然就是实现jdbc类型和java类型之间的转换,同时分析了BaseTypeHandler的setParameter()方法和getResult()方法,getNullableResult是抽象类,具体方法由其他实现类进行实现。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。