MyBatis類型處理器TypeHandler的作用及說明
TypeHandler 是 MyBatis 中用于處理 Java 類型與 JDBC 類型之間轉(zhuǎn)換的接口。它在 MyBatis 的參數(shù)綁定和結(jié)果映射過程中起著至關(guān)重要的作用。
為什么需要 TypeHandler?
Java 和 數(shù)據(jù)庫(JDBC)使用不同的類型系統(tǒng)。例如:
- Java 中有
String、Integer、Date、Boolean、enum等類型。 - JDBC 中有
VARCHAR、INTEGER、DATE、BOOLEAN、TIMESTAMP、BLOB等類型。
當(dāng) MyBatis 執(zhí)行 SQL 語句時(shí),需要將 Java 對(duì)象中的數(shù)據(jù)設(shè)置到 JDBC 的 PreparedStatement 中(參數(shù)綁定),以及將 JDBC 的 ResultSet 中的數(shù)據(jù)轉(zhuǎn)換為 Java 對(duì)象(結(jié)果映射)。TypeHandler 就負(fù)責(zé)處理這兩種情況下的類型轉(zhuǎn)換。
TypeHandler 的作用
參數(shù)綁定 (Java 類型 -> JDBC 類型):
- 當(dāng) MyBatis 將 Java 對(duì)象中的數(shù)據(jù)設(shè)置到
PreparedStatement的占位符(#{})時(shí),TypeHandler會(huì)將 Java 類型轉(zhuǎn)換為對(duì)應(yīng)的 JDBC 類型。 - 例如,將 Java 的
String類型轉(zhuǎn)換為 JDBC 的VARCHAR類型,將 Java 的Date類型轉(zhuǎn)換為 JDBC 的TIMESTAMP類型。
結(jié)果映射 (JDBC 類型 -> Java 類型):
- 當(dāng) MyBatis 從
ResultSet中讀取數(shù)據(jù)并將其映射為 Java 對(duì)象時(shí),TypeHandler會(huì)將 JDBC 類型轉(zhuǎn)換為對(duì)應(yīng)的 Java 類型。 - 例如,將 JDBC 的
VARCHAR類型轉(zhuǎn)換為 Java 的String類型,將 JDBC 的INTEGER類型轉(zhuǎn)換為 Java 的Integer類型。
TypeHandler 的接口定義
public interface TypeHandler<T> {
// 參數(shù)綁定:將 Java 類型轉(zhuǎn)換為 JDBC 類型,并設(shè)置到 PreparedStatement 中
void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;
// 結(jié)果映射:從 ResultSet 中獲取指定列的數(shù)據(jù),并將其轉(zhuǎn)換為 Java 類型
T getResult(ResultSet rs, String columnName) throws SQLException;
// 結(jié)果映射:從 ResultSet 中獲取指定列索引的數(shù)據(jù),并將其轉(zhuǎn)換為 Java 類型
T getResult(ResultSet rs, int columnIndex) throws SQLException;
// 結(jié)果映射:從 CallableStatement 中獲取指定列索引的數(shù)據(jù),將其轉(zhuǎn)換為java類型
T getResult(CallableStatement cs, int columnIndex) throws SQLException;
}setParameter(): 將 Java 類型的參數(shù)parameter設(shè)置到PreparedStatement的第i個(gè)占位符,并指定 JDBC 類型jdbcType(jdbcType可以為空,MyBatis 會(huì)嘗試自動(dòng)推斷)。getResult(): 有三個(gè)重載方法,分別根據(jù)列名、列索引從ResultSet中獲取數(shù)據(jù),或從CallableStatement獲取數(shù)據(jù),并將其轉(zhuǎn)換為 Java 類型。
MyBatis 內(nèi)置的 TypeHandler
MyBatis 內(nèi)置了許多常用的 TypeHandler,用于處理常見的類型轉(zhuǎn)換。例如:
StringTypeHandler: 處理String類型。IntegerTypeHandler: 處理Integer類型。LongTypeHandler: 處理Long類型。DateTypeHandler: 處理java.util.Date類型。BooleanTypeHandler: 處理Boolean類型。EnumTypeHandler: 處理枚舉類型(默認(rèn)使用枚舉的名稱)。EnumOrdinalTypeHandler: 處理枚舉類型(使用枚舉的序數(shù))。BlobTypeHandler: 處理二進(jìn)制大對(duì)象 (BLOB)。ClobTypeHandler: 處理字符大對(duì)象 (CLOB)。SqlDateTypeHandler:處理java.sql.Date類型SqlTimeTypeHandler:處理java.sql.Time類型SqlTimestampTypeHandler:處理java.sql.Timestamp類型- …
自定義 TypeHandler
當(dāng) MyBatis 內(nèi)置的 TypeHandler 不能滿足需求時(shí),我們可以自定義 TypeHandler。例如:
- 處理特殊類型: 例如,將數(shù)據(jù)庫中的 JSON 字符串轉(zhuǎn)換為 Java 對(duì)象,或者將 Java 對(duì)象轉(zhuǎn)換為 JSON 字符串存儲(chǔ)到數(shù)據(jù)庫中。
- 自定義類型轉(zhuǎn)換邏輯: 例如,對(duì)日期類型進(jìn)行特殊的格式化,或者對(duì)枚舉類型使用自定義的轉(zhuǎn)換規(guī)則。
自定義 TypeHandler 的步驟
1.實(shí)現(xiàn) TypeHandler 接口: 創(chuàng)建一個(gè)類,實(shí)現(xiàn) TypeHandler 接口,并實(shí)現(xiàn)接口中的方法。
2.注冊(cè) TypeHandler: 有兩種方式注冊(cè)自定義的 TypeHandler:
- XML 配置: 在
mybatis-config.xml文件中,使用<typeHandlers>標(biāo)簽注冊(cè)TypeHandler。
<typeHandlers> <typeHandler handler="com.example.MyTypeHandler" javaType="com.example.MyType" jdbcType="VARCHAR"/> </typeHandlers>
- 或者使用包掃描:
<typeHandlers>
<package name="com.example.typehandler"/>
</typeHandlers>- 注解配置: 在自定義的
TypeHandler類上使用@MappedTypes和@MappedJdbcTypes注解。
@MappedTypes(MyType.class) // 指定 Java 類型
@MappedJdbcTypes(JdbcType.VARCHAR) // 指定 JDBC 類型
public class MyTypeHandler implements TypeHandler<MyType> {
// ... 實(shí)現(xiàn) TypeHandler 接口的方法 ...
}3.指定jdbcType(可選): 如果MyBatis無法推斷,則必須通過jdbcType屬性為null值指定數(shù)據(jù)庫列的類型
- 示例:
- 自定義一個(gè)將數(shù)據(jù)庫中的 VARCHAR 類型轉(zhuǎn)換為 Java 中的枚舉類型的 TypeHandler:
// 假設(shè)有一個(gè)枚舉類型
public enum Status {
ACTIVE, INACTIVE, PENDING
}
// 自定義 TypeHandler
@MappedTypes(Status.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class StatusTypeHandler implements TypeHandler<Status> {
@Override
public void setParameter(PreparedStatement ps, int i, Status parameter, JdbcType jdbcType) throws SQLException {
if (parameter == null) {
ps.setString(i, null);
} else {
ps.setString(i, parameter.name()); // 將枚舉的名稱存儲(chǔ)到數(shù)據(jù)庫
}
}
@Override
public Status getResult(ResultSet rs, String columnName) throws SQLException {
String value = rs.getString(columnName);
return getStatus(value);
}
@Override
public Status getResult(ResultSet rs, int columnIndex) throws SQLException {
String value = rs.getString(columnIndex);
return getStatus(value);
}
@Override
public Status getResult(CallableStatement cs, int columnIndex) throws SQLException {
String value = cs.getString(columnIndex);
return getStatus(value);
}
private Status getStatus(String value){
if (value == null) {
return null;
}
try {
return Status.valueOf(value); // 根據(jù)名稱從數(shù)據(jù)庫中獲取枚舉值
} catch (IllegalArgumentException e) {
return null; // 或者拋出異常
}
}
}
// 在 mybatis-config.xml 中注冊(cè) TypeHandler
<typeHandlers>
<typeHandler handler="com.example.StatusTypeHandler"/>
</typeHandlers>
// 或者在 Mapper XML 文件中使用
<resultMap id="userResultMap" type="User">
<result property="status" column="status" javaType="com.example.Status" jdbcType="VARCHAR" typeHandler="com.example.StatusTypeHandler"/>
</resultMap>
總結(jié)
TypeHandler 是 MyBatis 中用于處理 Java 類型與 JDBC 類型之間轉(zhuǎn)換的關(guān)鍵組件。
MyBatis 內(nèi)置了許多常用的 TypeHandler,在大多數(shù)情況下,我們可以直接使用內(nèi)置的 TypeHandler。
當(dāng)需要處理特殊類型或自定義類型轉(zhuǎn)換邏輯時(shí),我們可以自定義 TypeHandler,并通過 XML 配置或注解的方式注冊(cè)自定義的 TypeHandler。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- MyBatis自定義TypeHandler實(shí)現(xiàn)字段加密解密
- MyBatis中TypeHandler的使用教程詳解
- MyBatis-Plus?中?typeHandler?的使用實(shí)例詳解
- SpringBoot中MyBatis使用自定義TypeHandler的實(shí)現(xiàn)
- 解決Mybatis-plus自定義TypeHandler查詢映射結(jié)果一直為null問題
- Mybatis中TypeHandler使用小結(jié)
- Mybatis的TypeHandler實(shí)現(xiàn)數(shù)據(jù)加解密詳解
- Mybatis中自定義TypeHandler處理枚舉的示例代碼
- MyBatisPlus自定義JsonTypeHandler實(shí)現(xiàn)自動(dòng)轉(zhuǎn)化JSON問題
- MyBatis自定義TypeHandler如何解決字段映射問題
- MyBatis中TypeHandler基本用法與示例
相關(guān)文章
Java實(shí)現(xiàn)按字節(jié)長(zhǎng)度截取字符串
在Java中,由于字符串可能包含多字節(jié)字符,直接按字節(jié)長(zhǎng)度截取可能會(huì)導(dǎo)致亂碼或截取不準(zhǔn)確的問題,下面我們就來看看幾種按字節(jié)長(zhǎng)度截取字符串的方法吧2025-05-05
maven打包時(shí)配置多環(huán)境參數(shù)的實(shí)現(xiàn)
本文主要介紹了maven打包時(shí)配置多環(huán)境參數(shù)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-04-04
SpringBoot使用Maven打包異常-引入外部jar的問題及解決方案
這篇文章主要介紹了SpringBoot使用Maven打包異常-引入外部jar,需要的朋友可以參考下2020-06-06
java ssm框架實(shí)現(xiàn)分頁功能的示例代碼(oracle)
這篇文章主要介紹了java ssm框架實(shí)現(xiàn)分頁功能的示例代碼(oracle),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-03-03
elasticsearch設(shè)置賬號(hào)和密碼的完整代碼示例
這篇文章主要介紹了如何在Docker中安裝和配置Elasticsearch(ES)和Kibana,描述了如何設(shè)置Kibana的用戶和密碼,并解決由于ES默認(rèn)禁止使用超級(jí)用戶登錄Kibana的問題,需要的朋友可以參考下2025-01-01
解決Idea運(yùn)行junit測(cè)試時(shí)報(bào)Error:[3,17]?程序包org.junit不存在的問題
這篇文章主要介紹了Idea運(yùn)行junit測(cè)試時(shí)報(bào)Error:[3,17]?程序包org.junit不存在解決方法,本文給大家分享兩種解決辦法,需要的朋友可以參考下2023-03-03
SpringMVC?RESTFul實(shí)戰(zhàn)案例訪問首頁
這篇文章主要為大家介紹了SpringMVC?RESTFul實(shí)戰(zhàn)案例訪問首頁,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05

