当前使用版本(必填,否则不予处理)
implementation 'com.baomidou:mybatis-plus-boot-starter:3.4.3.4'
该问题是如何引起的?(确定最新版也有问题再提!!!)
实体类 Template.java
@TableName(value = "t_template", autoResultMap = true)
public class Template implements Serializable {
// 其他字段省略
@TableField(value = "F_config", typeHandler = PojoTypeHandler.class)
private Map<String, MyPojo> config;
}
DTO 类,MyPojo.java
public class MyPojo {
private String foo;
private String bar;
private Map<String, MyPojo> subLayer;
}
自定义 TypeHandler PojoTypeHandler.java
@MappedTypes({Object.class})
@MappedJdbcTypes(JdbcType.VARCHAR)
public class PojoTypeHandler extends BaseTypeHandler<Object> {
private static final ObjectMapper mapper = new ObjectMapper();
static {
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.registerModule(new JavaTimeModule());
}
private Class<?> clazz;
public PojoTypeHandler(Class<?> clazz) {
if (clazz == null) throw new IllegalArgumentException("Type argument cannot be null");
this.clazz = clazz;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, this.toJson(parameter));
}
@Override
public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
return this.toObject(rs.getString(columnName), clazz);
}
@Override
public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return this.toObject(rs.getString(columnIndex), clazz);
}
@Override
public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return this.toObject(cs.getString(columnIndex), clazz);
}
private String toJson(Object object) {
try {
return mapper.writeValueAsString(object);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Object toObject(String content, Class<?> clazz) {
if (content != null && !content.isEmpty()) {
try {
return mapper.readValue(content, clazz);
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
return null;
}
}
}
数据库 F_config 字段为 json 类型
重现步骤(如果有就写完整)
配置代码结构如上,构造一个 Template json 对象,用 save 方法可以正常存入数据库中,但是使用 getById 从数据库中查询出来的时候,丢失了 MyPojo 的类型信息。
期望返回中的 config 字段为 Map
类型定义
实际返回
报错信息
没有报错信息
Comment From: mabyoung
@wangx1ng 您好,有个疑问,如果返回的是 LinkedHashMap
Comment From: miemieYaho
泛型信息需要你自己维护,
Comment From: wangx1ng
@mabyoung 你好,把包含 detailedConfig 字段的实体查出来的时候,不会报任何错误,但是将 detailedConfig 取出来赋值给 Map
Comment From: wangx1ng
@miemieYaho 你好,请问,”需要我自己维护泛型信息“的含义是指: 在使用通用的 typehandler (@MappedTypes({Object.class}) )查出实体后,需要在客户代码中做手动类型转换吗?
目前我为每个需要自定义 typehanler 的字段都编写了具体类型的 typehandler,想知道能否多个需要自定义 typehandler 的字段都可以共用一个 PojoTypeHandler