最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL讀取JSON轉(zhuǎn)換的方式

 更新時(shí)間:2022年03月17日 16:32:33   作者:ItOYoung  
這篇文章主要介紹了MySQL讀取JSON轉(zhuǎn)換的方式,本文給大家分享兩種方式給大家講解處理方式,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下

存儲(chǔ)

mysql5.7+開始支持存儲(chǔ)JSON,后續(xù)不斷優(yōu)化,應(yīng)用也越來越廣泛
你可以自己將數(shù)據(jù)轉(zhuǎn)換成Json String后插入,也可以選擇使用工具,
而mybatis-plus就為此提供了非常簡便的方式,
只需要在字段上加上 @TableField(typeHandler = XxxTypeHandler.class),
mybatis-plus就會(huì)自動(dòng)幫你做轉(zhuǎn)換,通用一般就兩個(gè):
   - 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ǔ)類型以及對象來說沒有什么問題。
但如果存儲(chǔ)的字段類型是對象集合,那么當(dāng)你取出來時(shí),會(huì)發(fā)現(xiàn)集合中的對象都是JSONObject類型。
最常見的情況就拿出來進(jìn)行遍歷操作時(shí),會(huì)拋出強(qiáng)轉(zhuǎn)異常:
    java.lang.ClassCastException: com.alibaba.fastjson.JSONObject cannot be cast to ...
因?yàn)樘幚砥鲙湍戕D(zhuǎn)換時(shí),并不會(huì)存儲(chǔ)你集合的泛型,所以統(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就會(huì)將json轉(zhuǎn)換成javaType對應(yīng)的對象集合了

方式二:配置一個(gè)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;
    }
     * 將返回?cái)?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)文章

  • MySQL中的undo日志

    MySQL中的undo日志

    這篇文章主要介紹了MySQL中的undo日志的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)MySQL的相關(guān)知識(shí),感興趣的朋友可以了解下
    2020-11-11
  • mysql 操作數(shù)據(jù)庫基礎(chǔ)詳解

    mysql 操作數(shù)據(jù)庫基礎(chǔ)詳解

    這篇文章主要介紹了mysql 操作數(shù)據(jù)庫基礎(chǔ)詳解,MySQL是一種關(guān)系型數(shù)據(jù)庫管理系統(tǒng),關(guān)系數(shù)據(jù)庫將數(shù)據(jù)保存在不同的表中,而不是將所有數(shù)據(jù)放在一個(gè)大倉庫內(nèi),這樣就增加了速度并提高了靈活性
    2022-08-08
  • MyBatis攔截器實(shí)現(xiàn)分頁功能的實(shí)現(xiàn)方法

    MyBatis攔截器實(shí)現(xiàn)分頁功能的實(shí)現(xiàn)方法

    這篇文章主要介紹了MyBatis攔截器實(shí)現(xiàn)分頁功能的實(shí)現(xiàn)方法的相關(guān)資料,希望通過本文大家能夠?qū)崿F(xiàn)這樣的方法,需要的朋友可以參考下
    2017-10-10
  • textarea標(biāo)簽(存取數(shù)據(jù)庫mysql)的換行方法

    textarea標(biāo)簽(存取數(shù)據(jù)庫mysql)的換行方法

    textarea標(biāo)簽本身不識(shí)別換行功能,回車換行用的是\n換行符,輸入時(shí)的確有換行的效果,但是html渲染或者保存數(shù)據(jù)庫mysql時(shí)就只是一個(gè)空格了,這時(shí)就需要利用換行符\n和br標(biāo)簽的轉(zhuǎn)換進(jìn)行處理
    2023-09-09
  • CentOS 7中安裝mysql server的步驟分享

    CentOS 7中安裝mysql server的步驟分享

    這篇文章主要介紹了CentOS 7中安裝mysql server的步驟分享,需要的朋友可以參考下
    2015-09-09
  • MySQL中的數(shù)據(jù)類型binary和varbinary詳解

    MySQL中的數(shù)據(jù)類型binary和varbinary詳解

    binary和varbinary與char和varchar類型有點(diǎn)類似,不同的是binary和varbinary存儲(chǔ)的是二進(jìn)制的字符串,而非字符型字符串。下面這篇文章主要給大家介紹了關(guān)于MySQL中數(shù)據(jù)類型binary和varbinary的相關(guān)資料,介紹的非常詳細(xì),需要的朋友可以參考學(xué)習(xí)。
    2017-07-07
  • MySQL8.0 如何快速加列

    MySQL8.0 如何快速加列

    這篇文章主要介紹了MySQL8.0 如何快速加列,幫助大家更好的理解和使用MySQL數(shù)據(jù)庫,感興趣的朋友可以了解下
    2020-09-09
  • MySQL關(guān)閉密碼強(qiáng)度驗(yàn)證功能

    MySQL關(guān)閉密碼強(qiáng)度驗(yàn)證功能

    本文通過實(shí)例代碼給大家介紹了mysql關(guān)閉密碼強(qiáng)度驗(yàn)證功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-06-06
  • Mysql行轉(zhuǎn)列把逗號分隔的字段拆分成多行兩種方法

    Mysql行轉(zhuǎn)列把逗號分隔的字段拆分成多行兩種方法

    在數(shù)據(jù)庫中有時(shí)候我們需要將一些行數(shù)據(jù)轉(zhuǎn)換為列數(shù)據(jù),這在處理數(shù)據(jù)透視表、報(bào)表生成等場景下非常常見,這篇文章主要給大家介紹了關(guān)于Mysql行轉(zhuǎn)列把逗號分隔的字段拆分成多行的兩種方法,需要的朋友可以參考下
    2024-05-05
  • MySQL下高可用故障轉(zhuǎn)移方案MHA的超級部署教程

    MySQL下高可用故障轉(zhuǎn)移方案MHA的超級部署教程

    這篇文章主要介紹了MySQL下高可用故障切換方案MHA的超級部署教程,文中隊(duì)MHA方案的一些特點(diǎn)做了介紹,示例基于Linux系統(tǒng)的服務(wù)器環(huán)境,需要的朋友可以參考下
    2015-12-12

最新評論

扎囊县| 建湖县| 平乡县| 扶绥县| 奎屯市| 拜泉县| 化州市| 大宁县| 永嘉县| 永新县| 岳西县| 保德县| 天镇县| 唐山市| 关岭| 凭祥市| 金塔县| 青海省| 彭州市| 依兰县| 汉阴县| 双流县| 合川市| 溧阳市| 济宁市| 曲阳县| 广汉市| 信宜市| 邯郸县| 曲麻莱县| 锡林浩特市| 忻州市| 兴安县| 丘北县| 都兰县| 贵南县| 龙海市| 灌云县| 太和县| 克东县| 于田县|