一.报错背景

在使用mybatisPlus读取mysql的表的一个json字段,然后这个json对应的是java list 【List】,转化的时候抛了这个异常!

二.错误剖析

在这里插入图片描述
mybatisPlus的注解@TableField种指定的typeHandler如果使用 JacksonTypeHandler的话,会默认将数据库json字段映射成List,然后List中便是 LinkedHashMap, 《.》真的是遭重呀~~~~

三.解决方案

在这里插入图片描述

方案一

1.导入依赖:
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
2.类型转换:
 List<T> records = result.getData().getList();
  //使用ObjectMapper解决
  //创建一个ObjectMapper
  ObjectMapper mapper = new ObjectMapper();
  //OperLog就是需要的类型对象
  List<OperLog> operLogs= mapper.convertValue(records, new TypeReference<List<OperLog>>() {});

方案二

1.公共的ListTypeHandler
提供一个 JSONArray 转换为 Java List集合的处理器
@MappedJdbcTypes指定jdbc的类型
@MappedTypes指定Java的类型

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
 
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; 

@MappedJdbcTypes(JdbcType.ARRAY)
@MappedTypes({List.class})
public abstract class ListTypeHandler<T> extends BaseTypeHandler<List<T>>
{
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException {
        String content = CollUtil.isEmpty(parameter) ? null : JSON.toJSONString(parameter);
        ps.setString(i, content);
    }

    @Override
    public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return this.getListByJsonArrayString(rs.getString(columnName));
    }

    @Override
    public List<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return this.getListByJsonArrayString(rs.getString(columnIndex));
    }

    @Override
    public List<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return this.getListByJsonArrayString(cs.getString(columnIndex));
    }

    private List<T> getListByJsonArrayString(String content) {
        return StrUtil.isBlank(content) ? new ArrayList<>() : JSON.parseObject(content, this.specificType());
    }

    /**
     * 具体类型,由子类提供
     *
     * @return 具体类型
     */
    protected abstract TypeReference<List<T>> specificType();
}
2.具体的ListTypeHandler

由具体的子类提供List集合泛型类型

import com.alibaba.fastjson.TypeReference;
import com.chandol.entity.po.ReportUser;
import java.util.List;  

public class ReportUserListTypeHandler extends ListTypeHandler<ReportUser> { 
    @Override
    protected TypeReference<List<ReportUser>> specificType() {
        return new TypeReference<List<ReportUser>>() {
        };
    }    
}

在这里插入图片描述

我是杰叔叔,一名沪漂的码农,下期再会!

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐