MyBatis-Plus實(shí)現(xiàn)優(yōu)雅處理JSON字段映射
在使用 MyBatis-Plus 進(jìn)行業(yè)務(wù)開發(fā)時,我們時常需要把數(shù)據(jù)庫中的 JSON 字段(比如字符串形式的數(shù)組)自動映射成 Java 中的 JSONArray 或 List<String> 類型。
默認(rèn)情況下,MyBatis-Plus 是不支持直接映射 JSON 類型的,這時候就需要借助:
- @TableField(typeHandler = ...)
- 自定義或已有的 TypeHandler
- 配合 @TableName(autoResultMap = true) 才能正確生效!
真實(shí)場景舉例
假設(shè)我們現(xiàn)在有一個旅游美食表 travel_cuisine,里面的字段 tag_list 是一個 JSON Array,用來存儲標(biāo)簽 ID 列表,示例數(shù)據(jù)如下:
["tag-101", "tag-202", "tag-333"]
我們希望在 Java 實(shí)體中使用如下形式自動映射:
@TableField(typeHandler = JsonArrayTypeHandler.class) private JSONArray tagList;
接下來,教你一步步實(shí)現(xiàn)它。
一、@TableField + typeHandler 是什么?
@TableField 簡介
@TableField 是 MyBatis-Plus 提供的字段級注解,用于說明字段與數(shù)據(jù)庫的映射關(guān)系。
核心參數(shù)如下:
| 參數(shù) | 說明 |
|---|---|
value | 對應(yīng)數(shù)據(jù)庫字段名 |
exist | 字段是否存在于數(shù)據(jù)庫表結(jié)構(gòu)中 |
typeHandler | 字段轉(zhuǎn)換處理器,用于復(fù)雜類型映射 |
typeHandler 作用
TypeHandler 是 MyBatis 中的一個重要機(jī)制,它負(fù)責(zé)Java 類型 和 JDBC 類型之間的轉(zhuǎn)換。
你可以用它來處理:
- JSON ↔ Java 對象(如 JSONArray、Map、List)
- 逗號分隔字符串 ↔ List
- 枚舉 ↔ 數(shù)據(jù)庫存儲值
簡單來說,typeHandler 就是數(shù)據(jù)格式的橋梁!
二、@TableName(autoResultMap = true) 必須開啟
默認(rèn)情況下,MyBatis-Plus 的字段映射并不會使用 typeHandler,除非你在實(shí)體類加上:
@TableName(value = "travel_cuisine", autoResultMap = true)
autoResultMap 是什么?
這是告訴 MP:“請生成自定義的 ResultMap,否則我不支持 typeHandler 和復(fù)雜類型的轉(zhuǎn)換!”
如果你忘記加這一項(xiàng),typeHandler 是不會生效的!
三、實(shí)戰(zhàn)代碼:映射 JSON 字段為 JSONArray
1.數(shù)據(jù)庫建表語句(簡化版)
CREATE TABLE travel_cuisine ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100), tag_list TEXT -- JSON Array 字符串 );
2.實(shí)體類配置
@Data
@TableName(value = "travel_cuisine", autoResultMap = true)
public class TravelCuisineDO {
private Long id;
private String name;
@TableField(typeHandler = JsonArrayTypeHandler.class)
private JSONArray tagList;
}
3.自定義 TypeHandler(基于 FastJSON)
public class JsonArrayTypeHandler extends BaseTypeHandler<JSONArray> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, JSONArray parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, parameter.toJSONString());
}
@Override
public JSONArray getNullableResult(ResultSet rs, String columnName) throws SQLException {
String result = rs.getString(columnName);
return JSON.parseArray(result);
}
@Override
public JSONArray getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String result = rs.getString(columnIndex);
return JSON.parseArray(result);
}
@Override
public JSONArray getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String result = cs.getString(columnIndex);
return JSON.parseArray(result);
}
}
提醒:這個 JsonArrayTypeHandler 使用的是 FastJSON,如需 Jackson,請更換轉(zhuǎn)換邏輯。
四、常見問題排查指南
| 問題現(xiàn)象 | 解決方法或建議 |
|---|---|
| typeHandler 沒有生效 | 檢查實(shí)體類是否開啟 autoResultMap = true |
| 報 JSON parse error | 確保數(shù)據(jù)庫字段是真正的 JSON 格式 |
| 存儲時字段為 null | 確認(rèn)字段不是 transient,且未被忽略 |
| 想用 List<String> 代替 JSONArray | 寫一個 ListStringTypeHandler 即可 |
總結(jié):三件事必須配套使用
| 配置項(xiàng) | 說明 |
|---|---|
| @TableField(typeHandler = …) | 標(biāo)記字段轉(zhuǎn)換器 |
| @TableName(autoResultMap = true) | 告訴 MP 啟用復(fù)雜映射 |
| 自定義 TypeHandler | 將 JSON 字段與 Java 類型進(jìn)行互轉(zhuǎn) |
到此這篇關(guān)于MyBatis-Plus實(shí)現(xiàn)優(yōu)雅處理JSON字段映射的文章就介紹到這了,更多相關(guān)MyBatis-Plus處理JSON字段映射內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決mybatisplus插入報錯argument type mismatch的問題
這篇文章主要介紹了解決mybatisplus插入報錯argument type mismatch的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11
java int類型二維數(shù)組實(shí)現(xiàn)“楊輝三角”的完整實(shí)例
這篇文章主要給大家介紹了關(guān)于java int類型二維數(shù)組實(shí)現(xiàn)“楊輝三角”的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
Spring?Security實(shí)現(xiàn)用戶名密碼登錄詳解
這篇文章主要為大家詳細(xì)介紹了Spring Security如何實(shí)現(xiàn)用戶名密碼登錄功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2022-10-10
IDEA 設(shè)置顯示內(nèi)存的使用情況和內(nèi)存回收的方法
這篇文章主要介紹了IDEA 設(shè)置顯示內(nèi)存的使用情況和內(nèi)存回收的方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04
教你如何使用google.zxing結(jié)合springboot生成二維碼功能
這篇文章主要介紹了使用google.zxing結(jié)合springboot生成二維碼功能,我們使用兩種方式,去生成二維碼,但是其實(shí),二維碼的生成基礎(chǔ),都是zxing包,這是Google開源的一個包,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
基于SpringBoot和Vue的動態(tài)語音播放實(shí)現(xiàn)
本文介紹如何使用SpringBoot和Vue實(shí)現(xiàn)音頻文件的動態(tài)播放,包括前端頁面設(shè)計、后端接口開發(fā)、音頻文件存儲和調(diào)用等方面。通過該實(shí)現(xiàn),用戶可以在網(wǎng)頁上直接播放音頻,增強(qiáng)用戶體驗(yàn),提高網(wǎng)站互動性2023-04-04
java Socket編程實(shí)現(xiàn)I/O多路復(fù)用的示例
本文主要介紹了java Socket編程實(shí)現(xiàn)I/O多路復(fù)用的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-09-09
Spring中基于xml的AOP實(shí)現(xiàn)詳解
這篇文章主要介紹了Spring中基于xml的AOP實(shí)現(xiàn)詳解,基于xml與基于注解的AOP本質(zhì)上是非常相似的,都是需要封裝橫切關(guān)注點(diǎn),封裝到切面中,然后把橫切關(guān)注點(diǎn)封裝為一個方法,再把該方法設(shè)置為當(dāng)前的一個通知,再通過切入點(diǎn)表達(dá)式定位到橫切點(diǎn)就可以了,需要的朋友可以參考下2023-09-09

