新聞中心
Mybatis 在設(shè)置預(yù)處理語句(?PreparedStatement?)中的參數(shù)或從結(jié)果集中取出一個值時, 都會用類型處理器將獲取到的值以合適的方式轉(zhuǎn)換成 Java 類型。下表描述了一些默認的類型處理器。

從 3.4.5 開始,MyBatis 默認支持 JSR-310(日期和時間 API) 。
| 類型處理器 | Java 類型 | JDBC 類型 |
|---|---|---|
BooleanTypeHandler | java.lang.Boolean, boolean | 數(shù)據(jù)庫兼容的 BOOLEAN |
ByteTypeHandler | java.lang.Byte, byte | 數(shù)據(jù)庫兼容的 NUMERIC 或 BYTE |
ShortTypeHandler | java.lang.Short, short | 數(shù)據(jù)庫兼容的 NUMERIC 或 SMALLINT |
IntegerTypeHandler | java.lang.Integer, int | 數(shù)據(jù)庫兼容的 NUMERIC 或 INTEGER |
LongTypeHandler | java.lang.Long, long | 數(shù)據(jù)庫兼容的 NUMERIC 或 BIGINT |
FloatTypeHandler | java.lang.Float, float | 數(shù)據(jù)庫兼容的 NUMERIC 或 FLOAT |
DoubleTypeHandler | java.lang.Double, double | 數(shù)據(jù)庫兼容的 NUMERIC 或 DOUBLE |
BigDecimalTypeHandler | java.math.BigDecimal | 數(shù)據(jù)庫兼容的 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[] | 數(shù)據(jù)庫兼容的字節(jié)流類型 |
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 或任何兼容的字符串類型,用來存儲枚舉的名稱(而不是索引序數(shù)值) |
EnumOrdinalTypeHandler | Enumeration Type | 任何兼容的 NUMERIC 或 DOUBLE 類型,用來存儲枚舉的序數(shù)值(而不是名稱)。 |
SqlxmlTypeHandler | java.lang.String | SQLXML |
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.ZonedDateTime | TIMESTAMP |
YearTypeHandler | java.time.Year | INTEGER |
MonthTypeHandler | java.time.Month | INTEGER |
YearMonthTypeHandler | java.time.YearMonth | VARCHAR 或 LONGVARCHAR |
JapaneseDateTypeHandler | java.time.chrono.JapaneseDate | DATE |
你可以重寫已有的類型處理器或創(chuàng)建你自己的類型處理器來處理不支持的或非標準的類型。 具體做法為:實現(xiàn) ?org.apache.ibatis.type.TypeHandler? 接口, 或繼承一個很便利的類 ?org.apache.ibatis.type.BaseTypeHandler?, 并且可以(可選地)將它映射到一個 ?JDBC類型。比如:
// ExampleTypeHandler.java
@MappedJdbcTypes(JdbcType.VARCHAR)
public class ExampleTypeHandler extends BaseTypeHandler {
@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);
}
}
使用上述的類型處理器將會覆蓋已有的處理 Java ?String類型的屬性以及 ?VARCHAR ?類型的參數(shù)和結(jié)果的類型處理器。 要注意 MyBatis 不會通過檢測數(shù)據(jù)庫元信息來決定使用哪種類型,所以你必須在參數(shù)和結(jié)果映射中指明字段是 ?VARCHAR類型, 以使其能夠綁定到正確的類型處理器上。這是因為 MyBatis 直到語句被執(zhí)行時才清楚數(shù)據(jù)類型。
通過類型處理器的泛型,MyBatis 可以得知該類型處理器處理的 Java 類型,不過這種行為可以通過兩種方法改變:
- 在類型處理器的配置元素(?
typeHandler元素)上增加一個 ?javaType? 屬性(比如:?javaType="String"?); - 在類型處理器的類上增加一個 ?
@MappedTypes? 注解指定與其關(guān)聯(lián)的 Java 類型列表。 如果在 ?javaType屬性中也同時指定,則注解上的配置將被忽略。
可以通過兩種方式來指定關(guān)聯(lián)的 ?JDBC類型:
- 在類型處理器的配置元素上增加一個 ?
jdbcType屬性(比如:?jdbcType="VARCHAR"?); - 在類型處理器的類上增加一個 ?
@MappedJdbcTypes? 注解指定與其關(guān)聯(lián)的 ?JDBC類型列表。 如果在 ?jdbcType屬性中也同時指定,則注解上的配置將被忽略。
當(dāng)在 ?ResultMap中決定使用哪種類型處理器時,此時 Java 類型是已知的(從結(jié)果類型中獲得),但是 ?JDBC類型是未知的。 因此 Mybatis 使用?javaType=[Java 類型], jdbcType=null? 的組合來選擇一個類型處理器。 這意味著使用 ?@MappedJdbcTypes? 注解可以限制類型處理器的作用范圍,并且可以確保,除非顯式地設(shè)置,否則類型處理器在 ?ResultMap中將不會生效。 如果希望能在 ?ResultMap中隱式地使用類型處理器,那么設(shè)置 ?@MappedJdbcTypes? 注解的 ?includeNullJdbcType=true? 即可。 然而從 Mybatis 3.4.0 開始,如果某個 Java 類型只有一個注冊的類型處理器,即使沒有設(shè)置 ?includeNullJdbcType=true?,那么這個類型處理器也會是 ?ResultMap使用 Java 類型時的默認處理器。
最后,可以讓 MyBatis 幫你查找類型處理器:
注意在使用自動發(fā)現(xiàn)功能的時候,只能通過注解方式來指定JDBC的類型。
你可以創(chuàng)建能夠處理多個類的泛型類型處理器。為了使用泛型類型處理器, 需要增加一個接受該類的 class 作為參數(shù)的構(gòu)造器,這樣 MyBatis 會在構(gòu)造一個類型處理器實例的時候傳入一個具體的類。
//GenericTypeHandler.java
public class GenericTypeHandler extends BaseTypeHandler {
private Class type;
public GenericTypeHandler(Class type) {
if (type == null) throw new IllegalArgumentException("Type argument cannot be null");
this.type = type;
}
... ?EnumTypeHandler和 ?EnumOrdinalTypeHandler都是泛型類型處理器,我們將會在接下來的部分詳細探討。
處理枚舉類型
若想映射枚舉類型 ?Enum?,則需要從 ?EnumTypeHandler或者 ?EnumOrdinalTypeHandler中選擇一個來使用。
比如說我們想存儲取近似值時用到的舍入模式。默認情況下,MyBatis 會利用 ?EnumTypeHandler來把 ?Enum值轉(zhuǎn)換成對應(yīng)的名字。
注意 ?EnumTypeHandler在某種意義上來說是比較特別的,其它的處理器只針對某個特定的類,而它不同,它會處理任意繼承了Enum的類。
不過,我們可能不想存儲名字,相反我們的DBA會堅持使用整形值代碼。那也一樣簡單:在配置文件中把EnumOrdinalTypeHandler加到typeHandlers中即可, 這樣每個 ?RoundingMode將通過他們的序數(shù)值來映射成對應(yīng)的整形數(shù)值。
但要是你想在一個地方將Enum映射成字符串,在另外一個地方映射成整形值呢?
自動映射器(?auto-mapper?)會自動地選用 ?EnumOrdinalTypeHandler來處理枚舉類型, 所以如果我們想用普通的 ?EnumTypeHandler?,就必須要顯式地為那些 SQL 語句設(shè)置要使用的類型處理器。
(下一節(jié)才開始介紹映射器文件,如果你是首次閱讀該文檔,你可能需要先跳過這里,過會再來看。)
insert into users (id, name, funkyNumber, roundingMode) values (
#{id}, #{name}, #{funkyNumber}, #{roundingMode}
)
insert into users2 (id, name, funkyNumber, roundingMode) values (
#{id}, #{name}, #{funkyNumber}, #{roundingMode, typeHandler=org.apache.ibatis.type.EnumTypeHandler}
)
注意,這里的 ?select語句必須指定 ?resultMap而不是 ?resultType?。
分享題目:創(chuàng)新互聯(lián)MyBatis教程:MyBatis3XML配置-類型處理器
文章起源:http://m.5511xx.com/article/cdgchep.html


咨詢
建站咨詢
