1. 通用json字段转换器
package com.tophant.engine.data.jpa.convert;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
/**
* jpa json字段实体转换器,将字段转换成实体或List<String>
* 使用方式:字段上添加 @Convert(converter = SuperGenericAndJson.class)
* 注意:转换为List<实体>是里面的泛型不能转换成功,是 LinkedHashMap 类型,需要自定义转换器
*
* @author 万飞
* @date 2023/12/19
*/
@Converter
@RequiredArgsConstructor
@Slf4j
public class SuperGenericAndJson<T> implements AttributeConverter<T, String> {
private final ObjectMapper mapper;
@Override
public String convertToDatabaseColumn(T t) {
if(t == null){
return null;
}
try {
return mapper.writeValueAsString(t);
} catch (Exception e) {
log.error("【jpa json字段实体转换器】实体数据转为字段异常", e);
throw new RuntimeException(e.getMessage());
}
}
@Override
public T convertToEntityAttribute(String s) {
try {
if (s == null) {
return null;
}
T t = mapper.readValue(s, new TypeReference<T>() {
});
return t;
} catch (Exception e) {
log.error("【jpa json字段实体转换器】字段转为实体数据异常", e);
throw new RuntimeException(e.getMessage());
}
}
}
注意:
- 可以转换
实体对象
或List<String>
- 如果想转换为
List<实体对象>
,使用这个实际转换为List<LinkedHashMap>
,导致类型错误,可以使用下面的自定义转换器
参考 https://www.fcors.com/archives/1698
2. 自定义List<实体对象>
转换器
package com.tophant.asdb.server.common.convert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.tophant.asdb.sdk.common.ro.AssetDataSourcePriorityRo;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
/**
* 数据来源优先级字段转换---jpa json字段转换为 List<AssetDataSourcePriorityRo.AssetDataSourcePriorityFieldRo>
*
* @author 万飞
* @date 2023/12/20
*/
@Converter
public class DataSourcePriorityFieldConvert implements AttributeConverter<List<AssetDataSourcePriorityRo.AssetDataSourcePriorityFieldRo>, String> {
@Override
public String convertToDatabaseColumn(List<AssetDataSourcePriorityRo.AssetDataSourcePriorityFieldRo> assetDataSourcePriorityFieldRos) {
return JSONUtil.toJsonStr(Optional.ofNullable(assetDataSourcePriorityFieldRos).orElse(Collections.emptyList()));
}
@Override
public List<AssetDataSourcePriorityRo.AssetDataSourcePriorityFieldRo> convertToEntityAttribute(String s) {
if (StrUtil.isBlank(s)) {
return Collections.emptyList();
}
return JSONUtil.toBean(s, new TypeReference<List<AssetDataSourcePriorityRo.AssetDataSourcePriorityFieldRo>>() {
}, false);
}
}
3. 字段使用
/**
* 字段
*/
@Column(name = "fields", columnDefinition="jsonb")
@Convert(converter = DataSourcePriorityFieldConvert.class)
private List<AssetDataSourcePriorityRo.AssetDataSourcePriorityFieldRo> fields;