当前使用版本(必须填写清楚,否则不予处理)
3.3.0
自带的FastjsonTypeHandler配合@TableField处理字段时无法正确处理List<?>类型的数据,
查询时全部处理成了List
该问题是怎么引起的?(最新版上已修复的会直接close掉)
假设有个List<Demo>类型的属性注解了@TableField 在MP构造TableFieldInfo时只获取了List作为属性类型,所以在调用getResultMapping方法注册TypeHandler时只是把List.class传入
public class TableFieldInfo implements Constants {
……
public TableFieldInfo(GlobalConfig.DbConfig dbConfig, TableInfo tableInfo, Field field, TableField tableField) {
……
this.propertyType = field.getType();
……
}
……
ResultMapping getResultMapping(final MybatisConfiguration configuration) {
……
typeHandler = registry.getInstance(propertyType, this.typeHandler);
……
}
……
}
建议
给TableFieldInfo新增一个泛型属性genericType,构造时this.genericType=field.getGenericType(),注册时typeHandler = registry.getInstance(propertyType, genericType, this.typeHandler);
这样方便在FastjsonTypeHandler处理时获取到泛型直接调用JSON.parseObject(json, genericType);完成转换
Comment From: miemieYaho
内置 jsonTypeHandler 不适用于 list或 map或set
Comment From: nasodaengineer
内置 jsonTypeHandler 不适用于 list或 map或set
我知道不适用,所有建议加个泛型属性,这样我自定义的一个TypeHandler时也方便转换
Comment From: junxy
使用 数组代替泛型集合 可避坑
Comment From: simplechen
新版本已经支持
spring boot
pom.xml 部署配置
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
@Data public class KVNode implements Serializable {
private String key;
private String val;
private List<KVNode> nodes;
}
public class AppInfo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 应用名称
*/
private String name;
/**
* 应用属性
* 经验证 JacksonTypeHandler FastjsonTypeHandler都可以使用
*/
// @TableField(value="properties",typeHandler = JacksonTypeHandler.class)
@TableField(value="properties",typeHandler = FastjsonTypeHandler.class)
private List
控制器中使用 @RestController @RequestMapping("/app") public class AppInfoController {
@Autowired
private AppInfoMapper mapper;
@RequestMapping("/list")
public List
使用URL访问控制器输出 [ { id: 1, name: "sss", properties: [ { val: "shenzhen", nodes: null, key: "city" }, { val: "guangzhou", nodes: null, key: "city" } ] }, { id: 2, name: "sss", properties: [ { val: "shenzhen", nodes: null, key: "city" }, { val: "guangzhou", nodes: null, key: "city" } ] }, { id: 3, name: "sss", properties: [ { val: "shenzhen", nodes: null, key: "city" }, { val: "guangzhou", nodes: null, key: "city" } ] }, { id: 4, name: "sss", properties: [ { val: "shenzhen", nodes: [ ], key: "city" }, { val: "guangzhou", nodes: [ ], key: "city" } ] }, { id: 5, name: "sss", properties: [ { val: "shenzhen", nodes: [ ], key: "city" }, { val: "guangzhou", nodes: [ ], key: "city" } ] }, { id: 6, name: "sss", properties: [ { val: "shenzhen", nodes: [ ], key: "city" }, { val: "guangzhou", nodes: [ ], key: "city" } ] }, { id: 7, name: "sss", properties: [ { val: "shenzhen", nodes: [ ], key: "city" }, { val: "guangzhou", nodes: [ ], key: "city" } ] } ]
@MappedTypes({Object.class})
@MappedJdbcTypes(JdbcType.VARCHAR)
public class JsonTypeHandler
public JsonTypeHandler(Class<T> type) {
if(log.isTraceEnabled()) {
log.trace("JsonTypeHandler(" + type + ")");
}
if (type == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.type = type;
}
private T parse(String json) {
try {
if(json == null || json.length() == 0) {
return null;
}
return objectMapper.readValue(json, type);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private String toJsonString(Object obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
@Override
public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
return (T) parse(rs.getString(columnName));
}
@Override
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return (T) parse(rs.getString(columnIndex));
}
@Override
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return (T) parse(cs.getString(columnIndex));
}
@Override
public void setNonNullParameter(PreparedStatement ps, int columnIndex, T parameter, JdbcType jdbcType) throws SQLException {
ps.setString(columnIndex, toJsonString(parameter));
}
}