MyBatis配置项--typeHandlers

无论是MyBatis在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时,都会用类型处理器将获取的值以合适的方式转换成java类型。

可以重写类型处理器或创建自己的类型处理器来处理不支持的或非标准的类型。具体做法为:

实现org.apache.ibatis.type.TypeHandler接口,或继承一个很便利的类org.apache.ibatis.type.BaseTypeHandler,然后可选择性地将它映射到一个JDBC类型。比如:

// ExampleTypeHandler.java

@MappedJdbcTypes(JdbcType.VARCHAR)

public class ExampleTypeHandler extends BaseTypeHandler<String> {

 

  @Override

  public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {

    ps.setString(i, parameter);

  }

 

  @Override

  public String getNullableResult(ResultSet rs, String columnName) throws SQLException {

    return rs.getString(columnName);

  }

 

  @Override

  public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {

    return rs.getString(columnIndex);

  }

 

  @Override

  public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {

    return cs.getString(columnIndex);

  }

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<!-- mybatis-config.xml -->

<typeHandlers>

  <typeHandler handler="org.mybatis.example.ExampleTypeHandler"/>

</typeHandlers>

 

 

 

 

 

 

使用这个的类型处理器将会覆盖已经存在的处理java的String类型属性和VARCHAR参数及结果的类型处理器。

要注意MyBatis不会窥探数据库元信息来决定使用哪种类型,所以必须在参数和结果映射中指明那是VARCHAR类型的字段,以使其能够绑定到正确的类型处理器上。

这是因为:MyBatis直到语句被执行才清楚数据类型。

通过类型处理器的泛型,MyBatis可以得知该类型处理器处理的java类型,不过这种行为可以通过两种方法改变:

·在类型处理器的配置元素(typeHandler element)上增加一个javaType属性(比如:javaType=”String”);

·在类型处理器的类上(TypeHandler class)增加一个@MappedTypes注解来指定与其关联的java类型列表。如果是在javaType属性中也同时指定,则注解方式将被忽略。

可以通过两种方式来指定被关联的JDBC类型:

·在类型处理器的配置元素上增加一个jdbcType属性(比如:jdbcType=”VARCHAR”);

·在类型处理器的类上(TypeHandler class)增加一个@MappedJdbcTypes注解来指定与其关联的JDBC类型列表。如果在jdbcType属性中也同时指定,则注解方式将会被忽略。

当决定在ResultMap中使用某一TypeHandler时,此时java类型是已知的(从结果类型中获得),但是JDBC类型是未知的。

因此MyBatis使用javaType=[TheJavaType],jdbcType=null的组合来选择一个TypeHandler。

这意味着使用@MappedJdbcTypes注解可以限制TypeHandler的范围,同时除非显示的设置,否则TypeHandler在ResultMap中将是无效的。

如果希望在ResultMap中使用TypeHandler,那么设置@MappedJdbcTypes注解的includeNullJdbcType=true即可。

然而从MyBatis3.4.0开始,如果只有一个注册的TypeHandler来处理java类型,那么它将是ResultMap使用Java类型时的默认值(即使没有includeNullJdbcType=true)。

最后,可以让MyBatis为你查找类型处理器:

<!-- mybatis-config.xml -->

<typeHandlers>

  <package name="org.mybatis.example"/>

</typeHandlers>

 

 

 

 

 

 

注意在使用自动检索(autodiscovery)功能的时候,只能通过注解方式来指定JDBC的类型。

可以创建一个能够处理多个类的泛型类型处理器。

为了使用泛型类型处理器,需要增加一个接受该类的class作为参数的构造器,这样在构造一个类型处理器的时候MyBatis就会传入一个具体的类。

 

//GenericTypeHandler.java

public class GenericTypeHandler<E extends MyObject> extends BaseTypeHandler<E> {

 

  private Class<E> type;

 

  public GenericTypeHandler(Class<E> type) {

    if (type == null) throw new IllegalArgumentException("Type argument cannot be null");

    this.type = type;

  }

  ...

 

 

 

 

 

 

 

 

 

 

 

 

 

EnumTypeHandler和EnumOrdinalTypeHandler都是泛型类型处理器(generic TypeHandler)

 

下表描述了一些默认的类型处理器:

 

类型处理器

java类型

JDBC类型

BooleanTypeHandler

java.lang.Boolean,boolean

数据库兼容的BOOLEAN

ByteTypeHandler

java.lang.Byte,byte

数据库兼容的NUMERIC或BYTE

ShortTypeHandler

java.lang.Short,short

数据库兼容的NUMERIC或SHORT INTEGER

IntegerTypeHandler

java.lang.Integer,int

数据库兼容的NUMERIC或INTEGER

LongTypeHandler

java.lang.Long,long

数据库兼容的NUMERIC或LONG INTEGER

FloatTypeHandler

java.lang.Float,float

数据库兼容的NUMERIC或FLOAT

DoubleTypeHandler

java.lang.Double,double

数据库兼容的NUMERIC或DOUBLE

BigDecimalTypeHandler

java.math.BigDecimal

数据库兼容的NUMERIC或DECIMAL

StringTypeHandler

java.lang.String

CHAR,VARCHAR

ClobReaderTypeHandler

java.io.Reader

-

ClobTypeHandler

java.lang.String

CLOB,LONGVARCHAR

NStringTypeHandler

java.lang.String

NVARCHAR,NCHAR

NClobTypeHandler

java.lang.String

NCLOB

BlobInputStreamTypeHandler

java.io.InputStream

-

ByteArrayTypeHandler

byte[]

数据库兼容的字节流类型

BlobTypeHandler

byte[]

BLOB,LONGVARBINARY

DateTypeHandler

java.util.Date

TIMESTAMP

DateOnlyTypeHandler

java.util.Date

DATE

TimeOnlyTypeHandler

java.util.Date

TIME

SqlTimestampTypeHandler

java.sql.Timestamp

TIMESTAMP

SqlDateTypeHandler

java.sql.Date

DATE

SqlTimeTypeHandler

java.sql.Time

TIME

ObjectTypeHandler

Any

OTHER或未指定类型

EnumTypeHandler

Enumeration Type

VARCHAR-任何兼容的字符串类型,存储枚举的名称(而不是索引)

EnumOrdinalTypeHandler

Enumeration Type

任何兼容的NUMERIC或DOUBLE类型,存储枚举的索引(而不是名称)

InstantTypeHandler

java.time.Instant

TIMESTAMP

LocalDateTimeTypeHandler

java.time.LocalDateTime

TIMESTAMP

LocalDateTypeHandler

java.time.LocalDate

DATE

LocalTimeTypeHandler

java.time.LocalTime

Time

OffsetDateTimeTypeHandler

java.time.OffsetDateTime

TIMESTAMP

OffsetTimeTypeHandler

java.time.OffsetTime

TIME

ZonedDateTimeTypeHandler

java.time.ZoneDateTime

TIMESTAMP

YearTypeHandler

java.time.Year

INTEGER

MonthTypeHandler

java.time.Month

INTEGER

YearMonthTypeHandler

java.time.YearMonth

VARCHAR or LONGVARCHAR

JapaneseDateTypeHandler

java.time.chrono.JapaneseDate

DATE

posted on 2019-02-01 11:28  arrows  阅读(346)  评论(0编辑  收藏  举报

导航