SpringBoot中MyBatis使用自定義TypeHandler的實(shí)現(xiàn)
1. 前言
在 Spring Boot 項(xiàng)目中集成 MyBatis 時(shí),我們有時(shí)需要處理數(shù)據(jù)庫(kù)字段與 Java 對(duì)象屬性之間的特殊轉(zhuǎn)換,這時(shí)可以使用 MyBatis 提供的自定義 TypeHandler
。TypeHandler
是 MyBatis 用于在 JDBC 和 Java 類型之間進(jìn)行映射的接口。當(dāng)默認(rèn)的類型映射不能滿足需求時(shí),自定義 TypeHandler
就非常有用。
本章節(jié)就跟著博主一起來(lái)學(xué)習(xí)如何自定義TypeHandler
。
2. 自定義TypeHandler的應(yīng)用場(chǎng)景
日常開(kāi)發(fā)過(guò)程種自定義 TypeHandler
主要用于以下場(chǎng)景:
- 數(shù)據(jù)庫(kù)中的字段類型與 Java 中的字段類型不匹配,例如數(shù)據(jù)庫(kù)中存儲(chǔ) JSON 字符串,而在 Java 中使用自定義的對(duì)象。
- 數(shù)據(jù)庫(kù)中的枚舉值需要與 Java 枚舉進(jìn)行映射。
- 需要對(duì)數(shù)據(jù)庫(kù)的特殊字段類型進(jìn)行自定義的序列化和反序列化處理。例如:數(shù)據(jù)庫(kù)中逗號(hào)分隔字符串轉(zhuǎn)換為L(zhǎng)ist集合
3. 實(shí)現(xiàn)自定義 TypeHandler
假設(shè)我們有一個(gè)需求,數(shù)據(jù)庫(kù)中存儲(chǔ)了一個(gè) JSON 字符串,如:
{"city":"廣州市", "street":"天河區(qū)棠下街道"}
而我們希望在 Java 中將其映射為一個(gè)對(duì)象。首先,我們定義一個(gè)簡(jiǎn)單的對(duì)象類 Address
。
package com.example.demo.model; public class Address { private String street; private String city; // getters and setters public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } }
接下來(lái),我們實(shí)現(xiàn)自定義的 TypeHandler
,將 JSON 字符串轉(zhuǎn)換為 Address
對(duì)象。
package com.example.demo.typehandler; import com.example.demo.model.Address; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import java.sql.*; public class AddressTypeHandler extends BaseTypeHandler<Address> { private static final ObjectMapper objectMapper = new ObjectMapper(); @Override public void setNonNullParameter(PreparedStatement ps, int i, Address parameter, JdbcType jdbcType) throws SQLException { try { ps.setString(i, objectMapper.writeValueAsString(parameter)); } catch (JsonProcessingException e) { throw new SQLException("Error converting Address to String", e); } } @Override public Address getNullableResult(ResultSet rs, String columnName) throws SQLException { String json = rs.getString(columnName); return parseAddress(json); } @Override public Address getNullableResult(ResultSet rs, int columnIndex) throws SQLException { String json = rs.getString(columnIndex); return parseAddress(json); } @Override public Address getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { String json = cs.getString(columnIndex); return parseAddress(json); } private Address parseAddress(String json) throws SQLException { if (json == null) { return null; } try { return objectMapper.readValue(json, Address.class); } catch (JsonProcessingException e) { throw new SQLException("Error converting String to Address", e); } } }
4. 在 MyBatis 配置中使用 TypeHandler
要讓 MyBatis 知道我們的自定義 TypeHandler
,可以在 mybatis-config.xml
中進(jìn)行配置,或者通過(guò)注解的方式。
方式一:在mybatis-config.xml中配置
<typeHandlers> <typeHandler handler="com.example.demo.typehandler.AddressTypeHandler" javaType="com.example.demo.model.Address" jdbcType="VARCHAR"/> </typeHandlers>
方式二:使用注解配置
在 Mapper
接口的方法上直接使用 @Result
注解配置:
package com.example.demo.mapper; import com.example.demo.model.Address; import com.example.demo.model.User; import com.example.demo.typehandler.AddressTypeHandler; import org.apache.ibatis.annotations.*; import java.util.List; @Mapper public interface UserMapper { @Select("SELECT id, name, address FROM user WHERE id = #{id}") @Results({ @Result(column = "address", property = "address", typeHandler = AddressTypeHandler.class) }) User findById(int id); @Insert("INSERT INTO user(name, address) VALUES(#{name}, #{address, typeHandler=com.example.demo.typehandler.AddressTypeHandler})") @Options(useGeneratedKeys = true, keyProperty = "id") int insert(User user); }
5. 在實(shí)體類中應(yīng)用自定義TypeHandler
假設(shè)我們有一個(gè) User
類,其中包含 Address
字段。
package com.example.demo.model; public class User { private int id; private String name; private Address address; // getters and setters public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } }
6. 總結(jié)
在 Spring Boot
項(xiàng)目中集成 MyBatis
時(shí),自定義 TypeHandler
是處理數(shù)據(jù)庫(kù)與 Java 對(duì)象之間復(fù)雜轉(zhuǎn)換的重要工具。通過(guò) TypeHandler
,我們可以輕松實(shí)現(xiàn)如 JSON 字符串與 Java 對(duì)象之間的轉(zhuǎn)換、枚舉映射、以及其他復(fù)雜的數(shù)據(jù)類型轉(zhuǎn)換。靈活運(yùn)用 TypeHandler
可以簡(jiǎn)化代碼邏輯,提高項(xiàng)目的可維護(hù)性。
自定義 TypeHandler
適用于處理那些不能被 MyBatis 默認(rèn)處理的場(chǎng)景。在實(shí)際開(kāi)發(fā)中,建議根據(jù)業(yè)務(wù)需求合理使用 TypeHandler
,確保數(shù)據(jù)的準(zhǔn)確性和一致性。
到此這篇關(guān)于SpringBoot中MyBatis使用自定義TypeHandler的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)MyBatis自定義TypeHandler內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MyBatis?typeHandler接口的定義和使用
- MyBatis中的自定義TypeHandler詳解
- Mybatis中自定義TypeHandler處理枚舉的示例代碼
- Mybatis的TypeHandler實(shí)現(xiàn)數(shù)據(jù)加解密詳解
- Mybatis中TypeHandler使用小結(jié)
- Mybatis使用typeHandler加密的實(shí)現(xiàn)
- MyBatis-Plus?中?typeHandler?的使用實(shí)例詳解
- MyBatis中TypeHandler的使用教程詳解
- MyBatis類型處理器TypeHandler的作用及說(shuō)明
- MyBatis自定義TypeHandler實(shí)現(xiàn)字段加密解密
相關(guān)文章
使用Sentinel實(shí)現(xiàn)流控和服務(wù)降級(jí)的代碼示例
Sentinel是面向分布式、多語(yǔ)言異構(gòu)化服務(wù)架構(gòu)的流量治理組件,本文將詳細(xì)為大家介紹如何使用Sentinel實(shí)現(xiàn)流控和服務(wù)降級(jí),文中有相關(guān)的代碼示例,需要的朋友可以參考下2023-05-05MybatisX-Generator自動(dòng)代碼生成插件教程
這篇文章主要介紹了MybatisX-Generator自動(dòng)代碼生成插件教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04SpringBoot集成Prometheus實(shí)現(xiàn)監(jiān)控的過(guò)程
這篇文章主要介紹了SpringBoot集成Prometheus實(shí)現(xiàn)監(jiān)控,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09詳解Java 反射和反射的應(yīng)用場(chǎng)景
這篇文章主要介紹了Java 反射和反射的應(yīng)用場(chǎng)景的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java反射的相關(guān)知識(shí),感興趣的朋友可以了解下2020-08-08Java多線程(單例模式,堵塞隊(duì)列,定時(shí)器)詳解
這篇文章主要介紹了java多線程的(單例模式,堵塞隊(duì)列,定時(shí)器),具有一定參考價(jià)值,加深多線程編程的理解還是很有幫助的,需要的朋友可以參考下2021-08-08Spring中的SpringData詳細(xì)說(shuō)明
這篇文章主要介紹了Spring中的SpringData詳細(xì)說(shuō)明,Spring Data 是Spring 的一個(gè)子項(xiàng)目, 旨在統(tǒng)一和簡(jiǎn)化對(duì)各類型持久化存儲(chǔ), 而不拘泥于是關(guān)系型數(shù)據(jù)庫(kù)還是NoSQL 數(shù)據(jù)存儲(chǔ),需要的朋友可以參考下2023-11-11Eureka源碼閱讀解析Server服務(wù)端啟動(dòng)流程實(shí)例
這篇文章主要為大家介紹了Eureka源碼閱讀解析Server服務(wù)端啟動(dòng)流程實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10新手了解java 數(shù)組基礎(chǔ)知識(shí)
這篇文章主要介紹了Java 數(shù)組分析及簡(jiǎn)單實(shí)例的相關(guān)資料,在Java中它就是對(duì)象,一個(gè)比較特殊的對(duì)象,需要的朋友可以參考下,希望可以對(duì)你有所幫助2021-07-07springboot中用fastjson處理返回值為null的屬性值
在本篇文章里小編給大家整理的是一篇關(guān)于springboot中用fastjson處理返回值問(wèn)題詳解內(nèi)容,需要的朋友們參考下。2020-03-03