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 語句時,需要將 Java 對象中的數(shù)據(jù)設(shè)置到 JDBC 的 PreparedStatement 中(參數(shù)綁定),以及將 JDBC 的 ResultSet 中的數(shù)據(jù)轉(zhuǎn)換為 Java 對象(結(jié)果映射)。TypeHandler 就負(fù)責(zé)處理這兩種情況下的類型轉(zhuǎn)換。
TypeHandler 的作用
參數(shù)綁定 (Java 類型 -> JDBC 類型):
- 當(dāng) MyBatis 將 Java 對象中的數(shù)據(jù)設(shè)置到
PreparedStatement的占位符(#{})時,TypeHandler會將 Java 類型轉(zhuǎn)換為對應(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 對象時,TypeHandler會將 JDBC 類型轉(zhuǎn)換為對應(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個占位符,并指定 JDBC 類型jdbcType(jdbcType可以為空,MyBatis 會嘗試自動推斷)。getResult(): 有三個重載方法,分別根據(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: 處理二進制大對象 (BLOB)。ClobTypeHandler: 處理字符大對象 (CLOB)。SqlDateTypeHandler:處理java.sql.Date類型SqlTimeTypeHandler:處理java.sql.Time類型SqlTimestampTypeHandler:處理java.sql.Timestamp類型- …
自定義 TypeHandler
當(dāng) MyBatis 內(nèi)置的 TypeHandler 不能滿足需求時,我們可以自定義 TypeHandler。例如:
- 處理特殊類型: 例如,將數(shù)據(jù)庫中的 JSON 字符串轉(zhuǎn)換為 Java 對象,或者將 Java 對象轉(zhuǎn)換為 JSON 字符串存儲到數(shù)據(jù)庫中。
- 自定義類型轉(zhuǎn)換邏輯: 例如,對日期類型進行特殊的格式化,或者對枚舉類型使用自定義的轉(zhuǎn)換規(guī)則。
自定義 TypeHandler 的步驟
1.實現(xiàn) TypeHandler 接口: 創(chuàng)建一個類,實現(xiàn) TypeHandler 接口,并實現(xiàn)接口中的方法。
2.注冊 TypeHandler: 有兩種方式注冊自定義的 TypeHandler:
- XML 配置: 在
mybatis-config.xml文件中,使用<typeHandlers>標(biāo)簽注冊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> {
// ... 實現(xiàn) TypeHandler 接口的方法 ...
}3.指定jdbcType(可選): 如果MyBatis無法推斷,則必須通過jdbcType屬性為null值指定數(shù)據(jù)庫列的類型
- 示例:
- 自定義一個將數(shù)據(jù)庫中的 VARCHAR 類型轉(zhuǎn)換為 Java 中的枚舉類型的 TypeHandler:
// 假設(shè)有一個枚舉類型
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()); // 將枚舉的名稱存儲到數(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 中注冊 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)換邏輯時,我們可以自定義 TypeHandler,并通過 XML 配置或注解的方式注冊自定義的 TypeHandler。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- MyBatis?typeHandler接口的定義和使用
- MyBatis中的自定義TypeHandler詳解
- Mybatis中自定義TypeHandler處理枚舉的示例代碼
- Mybatis的TypeHandler實現(xiàn)數(shù)據(jù)加解密詳解
- Mybatis中TypeHandler使用小結(jié)
- SpringBoot中MyBatis使用自定義TypeHandler的實現(xiàn)
- Mybatis使用typeHandler加密的實現(xiàn)
- MyBatis-Plus?中?typeHandler?的使用實例詳解
- MyBatis中TypeHandler的使用教程詳解
- MyBatis自定義TypeHandler實現(xiàn)字段加密解密
相關(guān)文章
Java 程序設(shè)計總復(fù)習(xí)題(java基礎(chǔ)代碼)
這篇文章主要介紹了Java 程序設(shè)計總復(fù)習(xí)題,主要是java基礎(chǔ)代碼,方便學(xué)習(xí)java的同學(xué)2021-05-05
SpringBoot3+ShardingJDBC5.5.0 讀寫分離配置的實現(xiàn)
本文主要介紹了SpringBoot3+ShardingJDBC5.5.0 讀寫分離配置的實現(xiàn),最新版5.5.0支持SpringBoot3x現(xiàn)分享給大家,具有一定的參考價值,感興趣的可以了解一下2024-08-08
Java使用抽象工廠模式實現(xiàn)的肯德基消費案例詳解
這篇文章主要介紹了Java使用抽象工廠模式實現(xiàn)的肯德基消費案例,較為詳細的分析了抽象工廠模式的定義、原理并結(jié)合實例形式分析了Java使用抽象工廠模式實現(xiàn)肯德基消費案例的步驟與相關(guān)操作技巧,需要的朋友可以參考下2018-05-05

