问题:
有个需求需要用mysql存储集合数据,原来用mybatisplus自带的Wrapper获取的,只需要在实体类上加上(类型转换器)。
@TableField(typeHandler = FastjsonTypeHandler.class)
这样就可以了,因为mybatisplus 自己内部会自动识别这个注解,然后去解析数据存入集合。
实体定义如下:
@TableField(typeHandler = FastjsonTypeHandler.class)
private List<Integer> linkCrossIds;
数据库定义如下:
`link_cross_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
后面因为一些原因要改成mybatis的xml获取,这个时候去解析的一直是个null。
查了一些资料,在xml也要加一下类型转化器,因为实体类中的那个已经没用了。
解决方案
需要在resultMap中增加typeHandler,代码如下:
<resultMap id="CrossMap" type="com.mars.otncommon.model.po.VcCross">
<result column="link_cross_ids" property="linkCrossIds"
typeHandler="com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler"/>
</resultMap>
然后就能正常获取了。
一般来说 mybatisPlus 提供的 TypeHandler的FastjsonTypeHandler 够用了,如果有其他需求,就只有自己自定义了。
自定义类型转换器
存Long类型的集合数据
如果想存储List的数据,但是数据库转换的时候会优先把类型转换为Integer,这时候就需要转换了,自定义代码如下:
@Slf4j
@MappedJdbcTypes(JdbcType.VARCHAR) // 数据库中该字段存储的类型
@MappedTypes(List.class) // 需要转换的对象
public class ListInteger2ListLongSerialize extends BaseTypeHandler<List<Long>> {
private static ObjectMapper objectMapper = new ObjectMapper();
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<Long> parameter, JdbcType jdbcType) throws SQLException {
ps.setObject(i, JSON.toJSONString(parameter));
}
@Override
public List<Long> getNullableResult(ResultSet rs, String columnName) throws SQLException {
return getLongs(rs.getString(columnName));
}
@Override
public List<Long> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return getLongs(rs.getString(columnIndex));
}
@Override
public List<Long> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return getLongs(cs.getString(columnIndex));
}
private List<Long> getLongs(String value) {
if (StringUtils.hasText(value)) {
try {
CollectionType type = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Long.class);
return objectMapper.readValue(value, type);
//List<Long> longs = JsonUtil.parseArray(value, Long.class);
} catch (JsonProcessingException e) {
log.error("", e);
}
}
return null;
}
}
存枚举集合数据
@Slf4j
@MappedJdbcTypes(JdbcType.VARCHAR) // 数据库中该字段存储的类型
@MappedTypes(List.class) // 需要转换的对象
public class Enum2ListTypeSerialize extends BaseTypeHandler<List<Enum>> {
private static ObjectMapper objectMapper = new ObjectMapper();
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<Enum> parameter, JdbcType jdbcType) throws SQLException {
ps.setObject(i, JSON.toJSONString(parameter));
}
@Override
public List<Enum> getNullableResult(ResultSet rs, String columnName) throws SQLException {
return getLists(rs.getString(columnName));
}
@Override
public List<Enum> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return getLists(rs.getString(columnIndex));
}
@Override
public List<Enum> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return getLists(cs.getString(columnIndex));
}
private List<Enum> getLists(String value) {
if (StringUtils.hasText(value)) {
try {
CollectionType type = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Enum.class);
return objectMapper.readValue(value, type);
} catch (JsonProcessingException e) {
log.error("", e);
}
}
return null;
}