mybatis&plus系列------Mysql的JSON欄位的讀取和轉換
一. 背景
在平常的開發中,我們可能會有這樣的需求:
業務資料在儲存的時候,並不是以mysql中的varchar
丶int
等格式來儲存的,而是使用json
格式.
這樣做的好處是當資料結構有變化或者需求變化時,我們不用再新增欄位,方便擴充套件.
那麼mysql中json
格式的資料我們使用mybatis或者mybatisplus讀取以後,肯定是希望轉換成物件或者物件集合的,本篇博文就記錄一下使用mybatis
讀取json
格式的資料轉換為物件的方法
二. 資料準備
1. json欄位的新增
首先我們如果要使用sql語句來在表中新增一個json
格式的欄位,可以使用以下指令碼:
ALTER TABLE a ADD COLUMN alert_up_config json DEFAULT NULL COMMENT '註釋' AFTER id
以上sql執行以後,會在a
表的id
欄位之後,新增一個欄位alert_up_config
,它的格式就是json
新增完成以後,我們可以在這個欄位中儲存json物件或者json陣列格式的字串.
當前的業務場景是: alert_up_config
欄位中,是個jsonArr,儲存的是告警的升級規則,比如持續時間,次數等.
模擬資料如下:
[{"alertNum": 100, "alertLevel": "P1", "durationTime": 100, "resourceInfoId": "123456"}]
注意,使用json型別有2點需要注意:
- 儲存資料必須是json格式,否則會報錯
- json資料型別沒有預設值
三. 資料處理
1. 使用sql語句獲取json資料
首先我們可以使用sql語句來提取我們需要的json欄位,語法如下:
#json物件型別處理
JSON_EXTRACT(json列, '$.鍵')
#jsonArray型別處理, index從0開始計算
JSON_EXTRACT(json列, '$[index].鍵')
比如對於我們上面的示例資料,我們要查詢出alert_up_config
欄位中的alertNum
的值,可以使用如下語句:
select JSON_EXTRACT(alert_up_config, '$[0].alertNum') from a;
查詢結果如下:
2. 使用mybatis&mybatisPlus來讀取資料庫中的json資料
首先我們需要知道的是,mybatis提供了一個介面org.apache.ibatis.type.TypeHandler
來對資料庫中各種型別資料的處理,它主要有四個方法:
public interface TypeHandler<T> {
//儲存資料到資料庫之前的處理
void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;
//下面三個時候拿到資料以後的處理
T getResult(ResultSet rs, String columnName) throws SQLException;
T getResult(ResultSet rs, int columnIndex) throws SQLException;
T getResult(CallableStatement cs, int columnIndex) throws SQLException;
}
也就是說,如果我們要處理從mysql
中取出的資料,就可以實現這個介面,來自定義我們的資料處理邏輯,得到我們想要的資料.
現在對於我們來說,我們的源資料是這樣的:
[{"alertNum": 100, "alertLevel": "P1", "durationTime": 100, "resourceInfoId": "123456"}]
也有可能是這樣的:
{"alertNum": 100, "alertLevel": "P1", "durationTime": 100, "resourceInfoId": "123456"}
前者是JSONArray
,後者是JSONObject
對於前面的資料,我們可能會用List<AlertUpConfig>
這種格式來接收,如果是後者,我們可以使用AlertUpConfig
這種物件來直接接收資料.
現在,我們的需要mybatis或者mybatisplus幫助我們將資料庫中的json
資料自動轉換為相應的格式,一起來看下怎麼實現吧!
3. 使用mybatisplus實現json轉java物件/集合
在mybatisplus中,已經為我們提供了一系列的TypeHandler
有一個抽象類為: com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler
它抽象了json處理的方法:
public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, this.toJson(parameter));
}
public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
String json = rs.getString(columnName);
return StringUtils.isBlank(json) ? null : this.parse(json);
}
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String json = rs.getString(columnIndex);
return StringUtils.isBlank(json) ? null : this.parse(json);
}
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String json = cs.getString(columnIndex);
return StringUtils.isBlank(json) ? null : this.parse(json);
}
同時,它提供兩個抽象方法,用於提供給不同的json包:
protected abstract T parse(String json);
protected abstract String toJson(T obj);
我們看一下AbstractJsonTypeHandler
的實現類,可以發現有我們想要的東西:
很明顯,mybatisplus已經提供了FastJson
、Gson
和JackSon
的typehandler給我們使用.
下面是使用方法:
-
json轉java物件
如果不用
xml
檔案(xml的方式在mybatis部分說明),在實體物件相應的欄位上,用typeHandler
引數指定我們要使用的typeHandler
同時,在實體類上使用註解:
@TableName(value = "a", autoResultMap = true)
autoResultMap
參數列明欄位在查詢處理的時候自動轉換為物件@TableField(value = "alert_up_config", typeHandler = FastjsonTypeHandler.class) private AlertUpConfig alertUpConfig;
配置好以後,使用mapper查詢,可以發現
alert_up_config
欄位直接被轉換成了java物件
-
json轉List
4. 使用mybatis在xml中實現json轉java物件/集合
在xml中實現json和物件的轉換也比較簡單
<result column="alert_up_config" property="alertUpConfig" jdbcType="VARCHAR"
javaType="com.xxxx.AlertUpConfig"
typeHandler="com.xxxx.AlertUpConfigHandler"/>
同樣的handler,只是配置方式從註解改成xml中的屬性了.
需要注意的是,FastjsonTypeHandler
是mybatisplus提供的處理器,如果你的專案中沒有引入mp,那麼可以自己參照它寫一個.
結語:
在本篇博文中,介紹了資料庫json欄位和java物件,以及集合物件的相關轉換,記錄在這裡,以後有需要的時候可以及時查閱
個人公眾號<橙耘自留地>日前已經開通,後續博主釋出的文章都會一併更新到公眾號,如有需要,自行查閱.
關於橙耘自留地,是我個人聚焦網際網路技術棧學習分享的一個平臺,創立之初是因為目前業內各種技術課程資料層次不齊,褒貶不一,有時候一門課花費高價買入,其實內含草包,有時偶爾低價得之,卻又大有乾貨.因此我會根據大家的意見和評價,選擇不同的技術棧去學習,一為提升我自己的技術,二為大家梳理出質量比較好的課程,以作參考.同時,相關的學習心得也會一併更新到部落格和公眾號.