MySQL讀取JSON轉(zhuǎn)換的方式
存儲
mysql5.7+開始支持存儲JSON,后續(xù)不斷優(yōu)化,應(yīng)用也越來越廣泛 你可以自己將數(shù)據(jù)轉(zhuǎn)換成Json String后插入,也可以選擇使用工具, 而mybatis-plus就為此提供了非常簡便的方式, 只需要在字段上加上 @TableField(typeHandler = XxxTypeHandler.class), mybatis-plus就會自動幫你做轉(zhuǎn)換,通用一般就兩個: - com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler - com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler
例如
@Data @TableName(autoResultMap = true) public class Department implements Serializable { private static final long serialVersionUID = 203788572415896870L; @TableField(typeHandler = FastjsonTypeHandler.class) private List<Integer> userIds; }
存在什么問題?
如果使用通用處理器,那對于基礎(chǔ)類型以及對象來說沒有什么問題。 但如果存儲的字段類型是對象集合,那么當(dāng)你取出來時,會發(fā)現(xiàn)集合中的對象都是JSONObject類型。 最常見的情況就拿出來進(jìn)行遍歷操作時,會拋出強(qiáng)轉(zhuǎn)異常: java.lang.ClassCastException: com.alibaba.fastjson.JSONObject cannot be cast to ... 因為處理器幫你轉(zhuǎn)換時,并不會存儲你集合的泛型,所以統(tǒng)統(tǒng)都按照Object類型來轉(zhuǎn)換了: @Override protected Object parse(String json) { return JSON.parseObject(json, type); }
例如下面這種形式的類:
@Data @TableName(autoResultMap = true) public class Department implements Serializable { private static final long serialVersionUID = 203788572415896870L; @TableId(value = "id", type = IdType.AUTO) private Integer id; @TableField(typeHandler = FastjsonTypeHandler.class) private List<User> users; @Data public static class USer implements Serializable { // ... } }
如何處理
方式一:自定義處理器,自己做類型轉(zhuǎn)換,這也是當(dāng)前最普遍的方式,但是對于存在List字段的對象,還需要在XxxMapper.xml中進(jìn)行resultMap配置
@MappedTypes({Object.class}) @MappedJdbcTypes(JdbcType.VARCHAR) public class ListFastJsonTypeHandler extends FastjsonTypeHandler { private final Class<? extends Object> type; public ListFastJsonTypeHandler(Class<?> type) { super(type); this.type = type; } /** * 自己將json轉(zhuǎn)換成list * @param json * @return */ @Override protected Object parse(String json) { return JSON.parseArray(json, this.type); }
<mapper namespace="com.xxx.cn.mapper.DepartmentMapper"> <resultMap id="BaseResultMap" type="com.xxx.cn.domain.Department"> <id property="id" column="id"/> <result property="users" column="users" jdbcType="VARCHAR" javaType="com.xxx.cn.domain.Department.User" typeHandler="com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler"/> </resultMap> </mapper>
配置完成后,ListFastJsonTypeHandler就會將json轉(zhuǎn)換成javaType對應(yīng)的對象集合了
方式二:配置一個Mybatis插件,攔截ResultSetHandler,將返回結(jié)果進(jìn)行處理。 這樣的好處就是不用寫自定義的處理器和在XxxMapper.xml中做配置,減少了工作
@Component @Intercepts({ @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class}) }) public class ResultSetInterceptor implements Interceptor { /** * json序列化規(guī)則 */ private final SerializerFeature[] serializerFeatures = { SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty }; @Override public Object intercept(Invocation invocation) throws Throwable { Object proceed = invocation.proceed(); if (containJSONObject(proceed)) { if (proceed instanceof Collection) { return JSON.parseArray(JSON.toJSONString(proceed, serializerFeatures), ((Collection<?>) proceed).toArray()[0].getClass()); } return JSON.parseObject(JSON.toJSONString(proceed, serializerFeatures), proceed.getClass()); } // if (proceed instanceof Collection) { // for (Object obj : ((Collection<?>) proceed)) { // parseJSON2Object(obj, obj.getClass()); // } // } else { // parseJSON2Object(proceed, proceed.getClass()); // } return proceed; } * 將返回數(shù)據(jù)中心的JSONObject對象轉(zhuǎn)換成正常的對象 * * @param obj * @param typeClass * @throws IllegalAccessException * @throws ClassNotFoundException private void parseJSON2Object(Object obj, Class<?> typeClass) throws IllegalAccessException, ClassNotFoundException { for (Field declaredField : typeClass.getDeclaredFields()) { declaredField.setAccessible(true); Object value = declaredField.get(obj); if (isNullValueField(value)) { continue; Type genericType = declaredField.getGenericType(); String fieldClassName = genericType.getTypeName(); if (genericType instanceof ParameterizedType) { fieldClassName = ((ParameterizedType) genericType).getActualTypeArguments()[0].getTypeName(); if (containJSONObject(value)) { if (value instanceof Collection) { declaredField.set(obj, JSON.parseArray(JSON.toJSONString(value, serializerFeatures), Class.forName(fieldClassName))); } else { declaredField.set(obj, JSON.parseObject(JSON.toJSONString(value, serializerFeatures), Class.forName(fieldClassName))); } * 判斷是否跳過字段 * @param value * @return private Boolean isNullValueField(Object value) { return null == value || "".equals(String.valueOf(value).trim()) || (value instanceof Collection && ((Collection<?>) value).size() == 0); * 判斷值是否包含JSONObject對象 private boolean containJSONObject(Object value) throws IllegalAccessException { if (isNullValueField(value)) { return false; if (value instanceof Collection) { for (Object obj : (Collection<?>) value) { if (obj instanceof JSONObject) { return true; if (obj instanceof Collection && containJSONObject(obj)) { for (Field declaredField : obj.getClass().getDeclaredFields()) { declaredField.setAccessible(true); Object fieldValue = declaredField.get(obj); if (isNullValueField(fieldValue)) { continue; } if (fieldValue instanceof JSONObject) { return true; if (fieldValue instanceof Collection && containJSONObject(fieldValue)) { } return value instanceof JSONObject; }
到此這篇關(guān)于MySQL讀取JSON轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)MySQL讀取JSON轉(zhuǎn)換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一次現(xiàn)場mysql重復(fù)記錄數(shù)據(jù)的排查處理實戰(zhàn)記錄
這篇文章主要給大家介紹了一次現(xiàn)場mysql重復(fù)記錄數(shù)據(jù)的排查處理記錄,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2021-10-10MySQL之終端Terminal(dos界面)管理數(shù)據(jù)庫、數(shù)據(jù)表、數(shù)據(jù)的基本操作
這篇文章主要介紹了MySQL之終端(Terminal)管理數(shù)據(jù)庫、數(shù)據(jù)表、數(shù)據(jù)的基本操作,需要的朋友可以參考下2015-03-03Mysql之EXPLAIN顯示using filesort介紹
EXPLAIN 是mysql解釋select查詢的一個關(guān)鍵字,可以很方便的用于調(diào)試2012-02-02Mysql更換MyISAM存儲引擎為Innodb的操作記錄總結(jié)
下面小編就為大家?guī)硪黄狹ysql更換MyISAM存儲引擎為Innodb的操作記錄總結(jié)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03Linux環(huán)境下安裝mysql5.7.36數(shù)據(jù)庫教程
大家好,本篇文章主要講的是Linux環(huán)境下安裝mysql5.7.36數(shù)據(jù)庫教程,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12