mybatis(五)typeHandlers

typeHandlers

無論是 MyBatis 在預處理語句(PreparedStatement)中設置一個參數時,還是從結果集中取出一個值時, 都會用類型處理器將獲取的值以合適的方式轉換成 Java 類型。下表描述了一些默認的類型處理器。

NOTE Since version 3.4.5, The MyBatis has been supported JSR-310(Date and Time API) by default.

類型處理器Java 類型JDBC 類型
BooleanTypeHandlerjava.lang.Booleanboolean數據庫兼容的 BOOLEAN
ByteTypeHandlerjava.lang.Bytebyte數據庫兼容的 NUMERIC 或 BYTE
ShortTypeHandlerjava.lang.Shortshort數據庫兼容的 NUMERIC 或 SHORT INTEGER
IntegerTypeHandlerjava.lang.Integerint數據庫兼容的 NUMERIC 或 INTEGER
LongTypeHandlerjava.lang.Longlong數據庫兼容的 NUMERIC 或 LONG INTEGER
FloatTypeHandlerjava.lang.Floatfloat數據庫兼容的 NUMERIC 或 FLOAT
DoubleTypeHandlerjava.lang.Doubledouble數據庫兼容的 NUMERIC 或 DOUBLE
BigDecimalTypeHandlerjava.math.BigDecimal數據庫兼容的 NUMERIC 或 DECIMAL
StringTypeHandlerjava.lang.StringCHARVARCHAR
ClobReaderTypeHandlerjava.io.Reader-
ClobTypeHandlerjava.lang.StringCLOBLONGVARCHAR
NStringTypeHandlerjava.lang.StringNVARCHARNCHAR
NClobTypeHandlerjava.lang.StringNCLOB
BlobInputStreamTypeHandlerjava.io.InputStream-
ByteArrayTypeHandlerbyte[]數據庫兼容的字節流類型
BlobTypeHandlerbyte[]BLOBLONGVARBINARY
DateTypeHandlerjava.util.DateTIMESTAMP
DateOnlyTypeHandlerjava.util.DateDATE
TimeOnlyTypeHandlerjava.util.DateTIME
SqlTimestampTypeHandlerjava.sql.TimestampTIMESTAMP
SqlDateTypeHandlerjava.sql.DateDATE
SqlTimeTypeHandlerjava.sql.TimeTIME
ObjectTypeHandlerAnyOTHER 或未指定類型
EnumTypeHandlerEnumeration TypeVARCHAR-任何兼容的字符串類型,存儲枚舉的名稱(而不是索引)
EnumOrdinalTypeHandlerEnumeration Type任何兼容的 NUMERIC 或 DOUBLE 類型,存儲枚舉的索引(而不是名稱)。
InstantTypeHandlerjava.time.InstantTIMESTAMP
LocalDateTimeTypeHandlerjava.time.LocalDateTimeTIMESTAMP
LocalDateTypeHandlerjava.time.LocalDateDATE
LocalTimeTypeHandlerjava.time.LocalTimeTIME
OffsetDateTimeTypeHandlerjava.time.OffsetDateTimeTIMESTAMP
OffsetTimeTypeHandlerjava.time.OffsetTimeTIME
ZonedDateTimeTypeHandlerjava.time.ZonedDateTimeTIMESTAMP
YearTypeHandlerjava.time.YearINTEGER
MonthTypeHandlerjava.time.MonthINTEGER
YearMonthTypeHandlerjava.time.YearMonthVARCHAR or LONGVARCHAR
JapaneseDateTypeHandlerjava.time.chrono.JapaneseDateDATE

你可以重寫類型處理器或創建你自己的類型處理器來處理不支持的或非標準的類型。 具體做法爲:實現 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即可。 然而從Mybatis 3.4.0開始,如果只有一個註冊的TypeHandler來處理Java類型,那麼它將是ResultMap使用Java類型時的默認值(即使沒有includeNullJdbcType=true)。

最後,可以讓 MyBatis 爲你查找類型處理器:

<!-- mybatis-config.xml -->
<typeHandlers>
  <package name="org.mybatis.example"/>
</typeHandlers>

注意在使用自動檢索(autodiscovery)功能的時候,只能通過註解方式來指定 JDBC 的類型。

你能創建一個泛型類型處理器,它可以處理多於一個類。爲達到此目的, 需要增加一個接收該類作爲參數的構造器,這樣在構造一個類型處理器的時候 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 TypeHandlers), 我們將會在接下來的部分詳細探討。


轉自:http://www.mybatis.org/mybatis-3/zh/configuration.html#properties

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章