MyBatis-Plus實(shí)現(xiàn)優(yōu)雅處理JSON字段映射
在使用 MyBatis-Plus 進(jìn)行業(yè)務(wù)開發(fā)時(shí),我們時(shí)常需要把數(shù)據(jù)庫中的 JSON 字段(比如字符串形式的數(shù)組)自動(dòng)映射成 Java 中的 JSONArray 或 List<String> 類型。
默認(rèn)情況下,MyBatis-Plus 是不支持直接映射 JSON 類型的,這時(shí)候就需要借助:
- @TableField(typeHandler = ...)
- 自定義或已有的 TypeHandler
- 配合 @TableName(autoResultMap = true) 才能正確生效!
真實(shí)場(chǎng)景舉例
假設(shè)我們現(xiàn)在有一個(gè)旅游美食表 travel_cuisine,里面的字段 tag_list 是一個(gè) JSON Array,用來存儲(chǔ)標(biāo)簽 ID 列表,示例數(shù)據(jù)如下:
["tag-101", "tag-202", "tag-333"]
我們希望在 Java 實(shí)體中使用如下形式自動(dòng)映射:
@TableField(typeHandler = JsonArrayTypeHandler.class) private JSONArray tagList;
接下來,教你一步步實(shí)現(xiàn)它。
一、@TableField + typeHandler 是什么?
@TableField 簡(jiǎn)介
@TableField 是 MyBatis-Plus 提供的字段級(jí)注解,用于說明字段與數(shù)據(jù)庫的映射關(guān)系。
核心參數(shù)如下:
參數(shù) | 說明 |
---|---|
value | 對(duì)應(yīng)數(shù)據(jù)庫字段名 |
exist | 字段是否存在于數(shù)據(jù)庫表結(jié)構(gòu)中 |
typeHandler | 字段轉(zhuǎn)換處理器,用于復(fù)雜類型映射 |
typeHandler 作用
TypeHandler 是 MyBatis 中的一個(gè)重要機(jī)制,它負(fù)責(zé)Java 類型 和 JDBC 類型之間的轉(zhuǎn)換。
你可以用它來處理:
- JSON ↔ Java 對(duì)象(如 JSONArray、Map、List)
- 逗號(hào)分隔字符串 ↔ List
- 枚舉 ↔ 數(shù)據(jù)庫存儲(chǔ)值
簡(jiǎn)單來說,typeHandler 就是數(shù)據(jù)格式的橋梁!
二、@TableName(autoResultMap = true) 必須開啟
默認(rèn)情況下,MyBatis-Plus 的字段映射并不會(huì)使用 typeHandler,除非你在實(shí)體類加上:
@TableName(value = "travel_cuisine", autoResultMap = true)
autoResultMap 是什么?
這是告訴 MP:“請(qǐng)生成自定義的 ResultMap,否則我不支持 typeHandler 和復(fù)雜類型的轉(zhuǎn)換!”
如果你忘記加這一項(xiàng),typeHandler 是不會(huì)生效的!
三、實(shí)戰(zhàn)代碼:映射 JSON 字段為 JSONArray
1.數(shù)據(jù)庫建表語句(簡(jiǎn)化版)
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); } }
提醒:這個(gè) JsonArrayTypeHandler 使用的是 FastJSON,如需 Jackson,請(qǐng)更換轉(zhuǎn)換邏輯。
四、常見問題排查指南
問題現(xiàn)象 | 解決方法或建議 |
---|---|
typeHandler 沒有生效 | 檢查實(shí)體類是否開啟 autoResultMap = true |
報(bào) JSON parse error | 確保數(shù)據(jù)庫字段是真正的 JSON 格式 |
存儲(chǔ)時(shí)字段為 null | 確認(rèn)字段不是 transient,且未被忽略 |
想用 List<String> 代替 JSONArray | 寫一個(gè) 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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot 使用yml配置文件給靜態(tài)變量賦值教程
這篇文章主要介紹了springboot 使用yml配置文件給靜態(tài)變量賦值教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-04-04Maven編譯錯(cuò)誤:程序包c(diǎn)om.sun.*包不存在的三種解決方案
J2SE中的類大致可以劃分為以下的各個(gè)包:java.*,javax.*,org.*,sun.*,本文文章主要介紹了maven編譯錯(cuò)誤:程序包c(diǎn)om.sun.xml.internal.ws.spi不存在的解決方案,感興趣的可以了解一下2024-02-02Java編程實(shí)現(xiàn)swing圓形按鈕實(shí)例代碼
這篇文章主要介紹了Java編程實(shí)現(xiàn)swing圓形按鈕實(shí)例代碼,涉及兩個(gè)簡(jiǎn)單的Java實(shí)現(xiàn)按鈕的代碼,其中一個(gè)具有偵測(cè)點(diǎn)擊事件的簡(jiǎn)單功能,具有一定借鑒價(jià)值,需要的朋友可以參考。2017-11-11JPA使用樂觀鎖應(yīng)對(duì)高并發(fā)方式
這篇文章主要介紹了JPA使用樂觀鎖應(yīng)對(duì)高并發(fā)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10Java面試題沖刺第十二天--數(shù)據(jù)庫(2)
這篇文章主要為大家分享了最有價(jià)值的三道數(shù)據(jù)庫面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下2021-07-07SpringBoot集成 Prometheus進(jìn)行高效監(jiān)控的實(shí)現(xiàn)
Prometheus作為一個(gè)開源的監(jiān)控和告警工具,以其強(qiáng)大的數(shù)據(jù)采集、存儲(chǔ)和查詢能力,受到了眾多開發(fā)者的青睞,本文主要介紹了SpringBoot集成 Prometheus進(jìn)行高效監(jiān)控的實(shí)現(xiàn),感興趣的可以了解一下2024-07-07Spring中的singleton和prototype的實(shí)現(xiàn)
這篇文章主要介紹了Spring中的singleton和prototype的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07