MyBatis中TypeHandler基本用法與示例
引入
在 MyBatis 中,TypeHandler 是一個(gè) 類型處理器,它的作用是處理數(shù)據(jù)庫(kù)中 JDBC 類型和 Java 類型之間的轉(zhuǎn)換。有時(shí)數(shù)據(jù)庫(kù)的字段類型和 Java 對(duì)象的字段類型不完全一致,或者我們希望對(duì)某些字段的映射 進(jìn)行定制化處理,這時(shí)就需要用到 TypeHandler。
TypeHandler 提供了一種靈活的機(jī)制,用于在 MyBatis 執(zhí)行 SQL 時(shí)對(duì)參數(shù)、返回值和數(shù)據(jù)庫(kù)列進(jìn)行類型轉(zhuǎn)換。MyBatis 提供了許多常見(jiàn)類型的默認(rèn)處理器(如字符串、整數(shù)、日期等),但在某些情況下,我們可能需要自定義 TypeHandler 來(lái)處理特定的數(shù)據(jù)轉(zhuǎn)換需求。
你可以重寫(xiě)已有的類型處理器或創(chuàng)建你自己的類型處理器來(lái)處理不支持的或非標(biāo)準(zhǔn)的類型。 具體做法為:實(shí)現(xiàn) org.apache.ibatis.type.TypeHandler 接口, 或繼承一個(gè)很便利的類 org.apache.ibatis.type.BaseTypeHandler, 并且可以(可選地)將它映射到一個(gè) JDBC 類型。
1.TypeHandler的作用
- 傳入?yún)?shù)時(shí)轉(zhuǎn)換類型:將 Java 對(duì)象中的屬性值轉(zhuǎn)換為適合 SQL 語(yǔ)句的 JDBC 類型。
- 查詢結(jié)果時(shí)轉(zhuǎn)換類型:將查詢結(jié)果中的字段值轉(zhuǎn)換為 Java 對(duì)象的屬性。
2.TypeHandler的接口
MyBatis 的 TypeHandler 是一個(gè)接口,主要有以下方法:
public interface TypeHandler<T> {
// 設(shè)置 PreparedStatement 的參數(shù)
void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;
// 從 ResultSet 獲取結(jié)果
T getResult(ResultSet rs, String columnName) throws SQLException;
T getResult(ResultSet rs, int columnIndex) throws SQLException;
T getResult(CallableStatement cs, int columnIndex) throws SQLException;
}
- setParameter:將參數(shù)值從 Java 類型轉(zhuǎn)換為 JDBC 類型,并設(shè)置到
PreparedStatement中。 - getResult:將查詢結(jié)果從數(shù)據(jù)庫(kù)的 JDBC 類型轉(zhuǎn)換為 Java 類型。
3.默認(rèn)的TypeHandler
MyBatis 默認(rèn)已經(jīng)為許多常見(jiàn)的 Java 類型提供了類型處理器。例如:
- String 類型:StringTypeHandler
- Integer 類型:IntegerTypeHandler
- Date 類型:DateTypeHandler
- Boolean 類型:BooleanTypeHandler
當(dāng)我們傳遞這些常見(jiàn)類型的對(duì)象時(shí),MyBatis 會(huì)自動(dòng)選擇合適的 TypeHandler 來(lái)執(zhí)行類型轉(zhuǎn)換。
4. 自定義TypeHandler的場(chǎng)景
雖然 MyBatis 提供了默認(rèn)的 TypeHandler,在某些特殊場(chǎng)景下,我們可能需要自定義 TypeHandler 來(lái)處理復(fù)雜的類型轉(zhuǎn)換。常見(jiàn)的應(yīng)用場(chǎng)景包括:
- 枚舉類型與數(shù)據(jù)庫(kù)值之間的映射:例如數(shù)據(jù)庫(kù)存儲(chǔ) 0 和 1 來(lái)表示枚舉值 YES 和 NO,在 Java 中則用枚舉來(lái)表示。
- JSON 字符串與對(duì)象之間的轉(zhuǎn)換:例如將 JSON 字符串轉(zhuǎn)換為 Java 對(duì)象(如使用 Gson 或 Jackson)。
- 日期格式不一致:例如數(shù)據(jù)庫(kù)存儲(chǔ)的是字符串日期格式,而 Java 中存儲(chǔ)的是 Date 類型,需要進(jìn)行格式轉(zhuǎn)換。
- 自定義的數(shù)據(jù)類型:例如數(shù)據(jù)庫(kù)中存儲(chǔ)的 VARCHAR 字段可以是某個(gè)自定義的類型,比如存儲(chǔ)一組特定格式的字符串,需要轉(zhuǎn)換為一個(gè)自定義對(duì)象。
5. 自定義TypeHandler實(shí)現(xiàn)
假設(shè)我們有一個(gè)場(chǎng)景,需要將數(shù)據(jù)庫(kù)中的 status 字段(存儲(chǔ)為字符串 “ACTIVE” 或 “INACTIVE”)映射為 Java 中的枚舉類型 Status。我們可以通過(guò)自定義 TypeHandler 來(lái)實(shí)現(xiàn)。
枚舉類型示例
枚舉類型 Status:
public enum Status {
ACTIVE("ACTIVE"),
INACTIVE("INACTIVE");
private final String value;
Status(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public static Status fromString(String value) {
for (Status status : Status.values()) {
if (status.getValue().equalsIgnoreCase(value)) {
return status;
}
}
return null;
}
}
自定義 TypeHandler:
@MappedTypes(Status.class) // 指定適用于 Status 類型
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, parameter.getValue()); // 將枚舉轉(zhuǎn)換為數(shù)據(jù)庫(kù)中的字符串
} else {
ps.setNull(i, Types.VARCHAR);
}
}
@Override
public Status getResult(ResultSet rs, String columnName) throws SQLException {
String value = rs.getString(columnName);
return Status.fromString(value); // 將數(shù)據(jù)庫(kù)中的字符串轉(zhuǎn)換為枚舉
}
@Override
public Status getResult(ResultSet rs, int columnIndex) throws SQLException {
String value = rs.getString(columnIndex);
return Status.fromString(value);
}
@Override
public Status getResult(CallableStatement cs, int columnIndex) throws SQLException {
String value = cs.getString(columnIndex);
return Status.fromString(value);
}
}
- setParameter:將枚舉類型的 Status 轉(zhuǎn)換為數(shù)據(jù)庫(kù)中的字符串(例如 “ACTIVE” 或 “INACTIVE”)。
- getResult:將從數(shù)據(jù)庫(kù)查詢結(jié)果中獲取的字符串轉(zhuǎn)換回 Status 枚舉類型。
在 MyBatis 中注冊(cè)和使用TypeHandler
- 注冊(cè) TypeHandler 的方式:
- 可以通過(guò) @MappedTypes 注解自動(dòng)注冊(cè)(如上例所示),在類型處理器的類上增加一個(gè) @MappedTypes 注解指定與其關(guān)聯(lián)的 Java 類型列表。 如果在 javaType 屬性中也同時(shí)指定,則注解上的配置將被忽略。
- 也可以在 MyBatis 配置文件中通過(guò) <typeHandlers> 配置進(jìn)行注冊(cè)。類型處理器的配置元素(typeHandler 元素)上增加一個(gè) javaType 屬性(比如:javaType="String");
- 可以通過(guò)兩種方式來(lái)指定關(guān)聯(lián)的 JDBC 類型:
- 在類型處理器的配置元素上增加一個(gè) jdbcType 屬性(比如:jdbcType="VARCHAR");
- 在類型處理器的類上增加一個(gè) @MappedJdbcTypes 注解指定與其關(guān)聯(lián)的 JDBC 類型列表。 如果在 jdbcType 屬性中也同時(shí)指定,則注解上的配置將被忽略。
下面給出在MyBatis 配置文件中通過(guò) <typeHandlers> 配置的示例:
<typeHandlers> <typeHandler handler="org.mybatis.example.ExampleTypeHandler" javaType="..." jdbcType="..."/> </typeHandlers>
查詢和插入示例
User 實(shí)體類:
public class User {
private Integer id;
private String username;
private Status status; // 使用自定義的枚舉類型
// Getters and Setters
}
Mapper 接口:
在@Result的typeHandler屬性中指定我們自定義的typeHandler
public interface UserMapper {
@Select("SELECT id, username, status FROM t_user WHERE id = #{id}")
@Results({
@Result(property = "status", column = "status", typeHandler = StatusTypeHandler.class)
})
User selectUserById(int id);
@Insert("INSERT INTO t_user (username, status) VALUES (#{username}, #{status, typeHandler=com.example.handler.StatusTypeHandler})")
void insertUser(User user);
}
這樣,在查詢時(shí)status 字段會(huì)使用 StatusTypeHandler 進(jìn)行轉(zhuǎn)換,插入時(shí)也會(huì)用 StatusTypeHandler 處理枚舉和數(shù)據(jù)庫(kù)字符串之間的轉(zhuǎn)換。
到此這篇關(guān)于MyBatis中TypeHandler基本用法與示例的文章就介紹到這了,更多相關(guān)MyBatis TypeHandler用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MyBatis自定義TypeHandler實(shí)現(xiàn)字段加密解密
- MyBatis類型處理器TypeHandler的作用及說(shuō)明
- MyBatis中TypeHandler的使用教程詳解
- MyBatis-Plus?中?typeHandler?的使用實(shí)例詳解
- SpringBoot中MyBatis使用自定義TypeHandler的實(shí)現(xiàn)
- 解決Mybatis-plus自定義TypeHandler查詢映射結(jié)果一直為null問(wèn)題
- Mybatis中TypeHandler使用小結(jié)
- Mybatis的TypeHandler實(shí)現(xiàn)數(shù)據(jù)加解密詳解
- Mybatis中自定義TypeHandler處理枚舉的示例代碼
- MyBatisPlus自定義JsonTypeHandler實(shí)現(xiàn)自動(dòng)轉(zhuǎn)化JSON問(wèn)題
- MyBatis自定義TypeHandler如何解決字段映射問(wèn)題
相關(guān)文章
SpringBoot創(chuàng)建監(jiān)聽(tīng)器的方法示例
在Java中,監(jiān)聽(tīng)器(Listener)是一種設(shè)計(jì)模式,它允許對(duì)象在 特定事件 發(fā)生時(shí) 自動(dòng)執(zhí)行某些操作,這種設(shè)計(jì)模式通常用于實(shí)現(xiàn) 發(fā)布-訂閱模型,本文給大家介紹了SpringBoot創(chuàng)建監(jiān)聽(tīng)器的方法示例,感興趣的通過(guò)可以參考一下2024-04-04
淺析Spring配置中的classpath:與classpath*:的區(qū)別
這篇文章主要介紹了Spring配置中的"classpath:"與"classpath*:"的區(qū)別,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
Java基于PDFbox實(shí)現(xiàn)讀取處理PDF文件
PDFbox是一個(gè)開(kāi)源的、基于Java的、支持PDF文檔生成的工具庫(kù),它可以用于創(chuàng)建新的PDF文檔,修改現(xiàn)有的PDF文檔,還可以從PDF文檔中提取所需的內(nèi)容。本文將具體介紹一下PDFbox讀取處理PDF文件的示例代碼,感興趣的可以學(xué)習(xí)一下2022-02-02
Java線程使用同步鎖交替執(zhí)行打印奇數(shù)偶數(shù)的方法
這篇文章主要介紹了Java線程使用同步鎖交替執(zhí)行打印奇數(shù)偶數(shù)的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
劍指Offer之Java算法習(xí)題精講排列與N叉樹(shù)
跟著思路走,之后從簡(jiǎn)單題入手,反復(fù)去看,做過(guò)之后可能會(huì)忘記,之后再做一次,記不住就反復(fù)做,反復(fù)尋求思路和規(guī)律,慢慢積累就會(huì)發(fā)現(xiàn)質(zhì)的變化2022-03-03
java實(shí)現(xiàn)國(guó)產(chǎn)sm4加密算法
這篇文章主要介紹了java實(shí)現(xiàn)國(guó)產(chǎn)sm4加密算法的步驟,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2020-12-12
詳解Spring緩存注解@Cacheable,@CachePut , @CacheEvict使用
這篇文章主要介紹了詳解Spring緩存注解@Cacheable,@CachePut , @CacheEvict使用,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-05-05
Springboot開(kāi)發(fā)OAuth2認(rèn)證授權(quán)與資源服務(wù)器操作
這篇文章主要介紹了Springboot開(kāi)發(fā)OAuth2認(rèn)證授權(quán)與資源服務(wù)器操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
Java TokenProcessor令牌校驗(yàn)工具類
這篇文章主要介紹了TokenProcessor令牌校驗(yàn)工具類 ,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-03-03
Java中if...else語(yǔ)句使用的學(xué)習(xí)教程
這篇文章主要介紹了Java中if...else語(yǔ)句使用的學(xué)習(xí)教程,是Java入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-11-11

