欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

存儲(chǔ)

mysql5.7+開(kāi)始支持存儲(chǔ)JSON,后續(xù)不斷優(yōu)化,應(yīng)用也越來(lái)越廣泛
你可以自己將數(shù)據(jù)轉(zhuǎn)換成Json String后插入,也可以選擇使用工具,
而mybatis-plus就為此提供了非常簡(jiǎn)便的方式,
只需要在字段上加上 @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;
}

存在什么問(wèn)題?

如果使用通用處理器,那對(duì)于基礎(chǔ)類型以及對(duì)象來(lái)說(shuō)沒(méi)有什么問(wèn)題。
但如果存儲(chǔ)的字段類型是對(duì)象集合,那么當(dāng)你取出來(lái)時(shí),會(huì)發(fā)現(xiàn)集合中的對(duì)象都是JSONObject類型。
最常見(jiàn)的情況就拿出來(lái)進(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類型來(lái)轉(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)前最普遍的方式,但是對(duì)于存在List字段的對(duì)象,還需要在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對(duì)應(yīng)的對(duì)象集合了

方式二:配置一個(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對(duì)象轉(zhuǎn)換成正常的對(duì)象
     *
     * @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)));
                }
     * 判斷是否跳過(guò)字段
     * @param value
     * @return
    private Boolean isNullValueField(Object value) {
        return null == value || "".equals(String.valueOf(value).trim())
                || (value instanceof Collection && ((Collection<?>) value).size() == 0);
     * 判斷值是否包含JSONObject對(duì)象
    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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論