Mybatis之類型處理器TypeHandler的作用與自定義方式
一、什么是類型處理器
1、類型處理器(TypeHandler)
MyBatis 在設(shè)置預(yù)處理語(yǔ)句(PreparedStatement)中的參數(shù)或從結(jié)果集中取出一個(gè)值時(shí),都會(huì)用類型處理器將獲取到的值以合適的方式轉(zhuǎn)換成 Java 類型。
說(shuō)人話,也就是java類型與jdbc類型之間的處換器,諸如最常見(jiàn)StringTypeHandler。

2、Mybatis內(nèi)置了哪些類型處理器
如下圖,類型處理器的頂級(jí)接口是org.apache.ibatis.type.TypeHandler

下表描述了一些默認(rèn)的類型處理器,官方原表。
| 類型處理器 | Java 類型 | JDBC 類型 |
|---|---|---|
| BooleanTypeHandler | java.lang.Boolean, boolean | 數(shù)據(jù)庫(kù)兼容的 BOOLEAN |
| ByteTypeHandler | java.lang.Byte, byte | 數(shù)據(jù)庫(kù)兼容的 NUMERIC 或 BYTE |
| ShortTypeHandler | java.lang.Short, short | 數(shù)據(jù)庫(kù)兼容的 NUMERIC 或 SMALLINT |
| IntegerTypeHandler | java.lang.Integer, int | 數(shù)據(jù)庫(kù)兼容的 NUMERIC 或 INTEGER |
| LongTypeHandler | java.lang.Long, long | 數(shù)據(jù)庫(kù)兼容的 NUMERIC 或 BIGINT |
| FloatTypeHandler | java.lang.Float, float | 數(shù)據(jù)庫(kù)兼容的 NUMERIC 或 FLOAT |
| DoubleTypeHandler | java.lang.Double, double | 數(shù)據(jù)庫(kù)兼容的 NUMERIC 或 DOUBLE |
| BigDecimalTypeHandler | java.math.BigDecimal | 數(shù)據(jù)庫(kù)兼容的 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ù)庫(kù)兼容的字節(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 或任何兼容的字符串類型,用來(lái)存儲(chǔ)枚舉的名稱(而不是索引序數(shù)值) |
| EnumOrdinalTypeHandler | Enumeration Type | 任何兼容的 NUMERIC 或 DOUBLE 類型,用來(lái)存儲(chǔ)枚舉的序數(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 |
二、如何自定義類型處理器
盡管mybatis提供了許多類型處理器,但有時(shí)由于業(yè)務(wù)的需要,需要自定義類型處理器。
例如,java實(shí)體類中Long[]數(shù)組類型如何以JSON字符串格式存儲(chǔ)到數(shù)據(jù)庫(kù)中varchar中,又如何能正常查詢出,此時(shí)就需要自定義類型了。
1、寫個(gè)處理器
實(shí)現(xiàn) org.apache.ibatis.type.TypeHandler 接口, 或繼承一個(gè)很便利的類org.apache.ibatis.type.BaseTypeHandler, 并且可以(可選地)將它映射到一個(gè) JDBC 類型

是否要指定javaType與jdbcType?
官方解釋:要注意 MyBatis 不會(huì)通過(guò)檢測(cè)數(shù)據(jù)庫(kù)元信息來(lái)決定使用哪種類型,所以你必須在參數(shù)和結(jié)果映射中指明字段的jdbcType,以使其能夠綁定到正確的類型處理器上。這是因?yàn)?MyBatis 直到語(yǔ)句被執(zhí)行時(shí)才清楚數(shù)據(jù)類型。
關(guān)于javaType的指定,通過(guò)類型處理器的泛型,MyBatis 可以得知該類型處理器處理的 Java 類型,不過(guò)這種行為可以通過(guò)兩種方法改變:
- 在類型處理器的配置元素(typeHandler 元素)上增加一個(gè) javaType 屬性(比如:javaType=“String”);
- 在類型處理器的類上增加一個(gè) @MappedTypes 注解指定與其關(guān)聯(lián)的 Java 類型列表。 如果在 javaType 屬性中也同時(shí)指定,則注解上的配置將被忽略。
關(guān)于jdbcType的指定,可以通過(guò)兩種方式來(lái)指定關(guān)聯(lián)的 JDBC 類型:
- 在類型處理器的配置元素上增加一個(gè) jdbcType 屬性(比如:jdbcType=“VARCHAR”);
- 在類型處理器的類上增加一個(gè) @MappedJdbcTypes 注解指定與其關(guān)聯(lián)的 JDBC 類型列表。 如果在 jdbcType 屬性中也同時(shí)指定,則注解上的配置將被忽略。
當(dāng)在 ResultMap 中決定使用哪種類型處理器時(shí),此時(shí) Java 類型是已知的(從結(jié)果類型中獲得),但是 JDBC 類型是未知的。 因此 Mybatis 使用 javaType=[Java 類型], jdbcType=null 的組合來(lái)選擇一個(gè)類型處理器。
這意味著使用 @MappedJdbcTypes 注解可以限制類型處理器的作用范圍,并且可以確保,除非顯式地設(shè)置,否則類型處理器在 ResultMap 中將不會(huì)生效。
如果希望能在 ResultMap 中隱式地使用類型處理器,那么設(shè)置 @MappedJdbcTypes 注解的 includeNullJdbcType=true 即可。
然而從 Mybatis 3.4.0 開(kāi)始,如果某個(gè) Java 類型只有一個(gè)注冊(cè)的類型處理器,即使沒(méi)有設(shè)置 includeNullJdbcType=true,那么這個(gè)類型處理器也會(huì)是 ResultMap 使用 Java 類型時(shí)的默認(rèn)處理器。
2、配置處理器
全局配置,在mybatis配置文件中配置

局部配置,只針對(duì)某個(gè)字段處理,查與增刪改使用的typeHandler要保持一致
查:在resultMap中指定字段的typeHandler

增刪改:使用 #{} 指定typeHandler

3、驗(yàn)證處理器
數(shù)據(jù)庫(kù):

實(shí)體類:

查詢結(jié)果:

插入結(jié)果:


總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Mybatis實(shí)現(xiàn)自定義的typehandler三步曲
- MyBatis自定義typeHandler的完整實(shí)例
- MyBatis-Plus如何通過(guò)注解使用TypeHandler
- Mybatis實(shí)現(xiàn)自定義類型轉(zhuǎn)換器TypeHandler的方法
- Mybatis中自定義TypeHandler處理枚舉詳解
- Mybatis自定義TypeHandler解決特殊類型轉(zhuǎn)換問(wèn)題詳解
- Mybatis實(shí)戰(zhàn)之TypeHandler高級(jí)進(jìn)階
- MyBatis使用自定義TypeHandler轉(zhuǎn)換類型的實(shí)現(xiàn)方法
- MyBatis-Plus?中?typeHandler?的使用實(shí)例詳解
- MyBatis中TypeHandler的使用教程詳解
- 一文搞懂MyBatis中TypeHandler機(jī)制
相關(guān)文章
Failed to execute goal org...的解決辦法
這篇文章主要介紹了Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1的解決辦法的相關(guān)資料,需要的朋友可以參考下2017-06-06
深入理解Spring事務(wù)及傳播機(jī)制之原理解析與實(shí)際應(yīng)用
Spring事務(wù)管理機(jī)制提供了多種傳播行為,可以控制事務(wù)的范圍和隔離級(jí)別,保證數(shù)據(jù)一致性和完整性。在實(shí)際應(yīng)用中,需要根據(jù)具體業(yè)務(wù)場(chǎng)景選擇合適的傳播行為實(shí)現(xiàn)事務(wù)控制2023-04-04
淺析mybatis和spring整合的實(shí)現(xiàn)過(guò)程
據(jù)官方的說(shuō)法,在Mybatis3問(wèn)世之前,Spring3的開(kāi)發(fā)工作就已經(jīng)完成了,所以Spring3中還是沒(méi)有對(duì)Mybatis3的支持。因此由Mybatis社區(qū)自己開(kāi)發(fā)了一個(gè)Mybatis-Spring用來(lái)滿足Mybatis用戶整合Spring的需求,下面通過(guò)Mybatis-Spring來(lái)整合Mybatis跟Spring的用法做介紹2015-10-10
Java編程調(diào)用微信接口實(shí)現(xiàn)圖文信息推送功能
這篇文章主要介紹了Java編程調(diào)用微信接口實(shí)現(xiàn)圖文信息等推送功能,涉及java微信圖文信息推送接口調(diào)用及相關(guān)文件、字符串編碼轉(zhuǎn)換相關(guān)操作技巧,需要的朋友可以參考下2017-08-08
SpringBoot集成Druid監(jiān)控頁(yè)面最小化配置操作
這篇文章主要介紹了SpringBoot集成Druid監(jiān)控頁(yè)面最小化配置操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
Javaweb開(kāi)發(fā)中通過(guò)Servlet生成驗(yàn)證碼圖片
這篇文章主要為大家詳細(xì)介紹了Javaweb開(kāi)發(fā)中通過(guò)Servlet生成驗(yàn)證碼圖片的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-05-05
Spring boot如何通過(guò)@Scheduled實(shí)現(xiàn)定時(shí)任務(wù)及多線程配置
這篇文章主要介紹了Spring boot如何通過(guò)@Scheduled實(shí)現(xiàn)定時(shí)任務(wù)及多線程配置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12
SpringCloud Gateway中斷言路由和過(guò)濾器的使用詳解
這篇文章主要介紹了SpringCloud Gateway中斷言路由和過(guò)濾器的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-04

