【实战场景】java.util.LinkedHashMap cannot be cast to XXXX 问题
【实战场景】java.util.LinkedHashMap cannot be cast to XXXX 问题
- 一.报错背景
- 二.错误剖析
- 三.解决方案
- 方案一
- 1.导入依赖:
- 2.类型转换:
- 方案二
- 1.公共的ListTypeHandler
- 2.具体的ListTypeHandler
- 我是杰叔叔,一名沪漂的码农,下期再会!
一.报错背景
在使用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>>() {
};
}
}