JPA JSON字符串与List以及对象的转换
有时为了方便,我们会吧对象或者List以JSON字符串的形式存放在数据库中。使用JPA就可以通过@Converte的方式实现。
JSON字符与对象的转换,我们比较常用的时jackson,maven依赖如下:
<dependencies>
<!--加入jackson库-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies>
JSONObject字符串转换为对象
这里以Order和Metadata为例。
1、首先创建用于转换Metadata对象的转换器。
@Converter(autoApply = true)
public class JSONConverter implements AttributeConverter<Metadata, String> {
private final static Logger LOGGER = LoggerFactory.getLogger(JSONConverter .class);
private final static ObjectMapper objectMapper = new ObjectMapper();
@Override
public String convertToDatabaseColumn(Metadata meta) {
try {
return objectMapper.writeValueAsString(meta);
} catch (JsonProcessingException ex) {
LOGGER.error("", ex);
return null;
}
}
@Override
public Metadata convertToEntityAttribute(String dbData) {
try {
return objectMapper.readValue(dbData, Metadata.class);
} catch (IOException ex) {
LOGGER.error("", ex);
return null;
}
}
}
代码实现了JPA转换器接口AttributeConverter
,这个接口提供了两个方法:
convertToDatabaseColumn
:用于把对象转换为数据库字段存储的值。convertToEntityAttribute
:用于把数据库里的字段存储的值转换为对象。
在convertToDatabaseColumn方法中,使用了Jackson的ObjectMapper
的writeValuAsString,把对象转换为JSONObject的字符串。
在convertToEntityAttribute方法中,也是用了Jackson的ObjectMapper
的readValue
方法,把字符串转换为对象。
2、在Order对象中添加注解@Convert
@Entity
@Table(name = "order")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Convert(converter = JSONConverter.class)
private Metadata metadata;
//…get 和set方法
}
JSONArray字符串转换为List
JSONArray与List之间的转换类似于对象的转换,但因为Jackson对List范类型的转换实现不同,所以在字符串转换List实现方式不同。
1、定义转换器
@Converter(autoApply = true)
public class OrderItemsJSONConverter implements AttributeConverter<List<OrderItem>, String> {
private final static Logger LOGGER = LoggerFactory.getLogger(ChaptersJSONConverter.class);
private final static ObjectMapper objectMapper = new ObjectMapper();
@Override
public String convertToDatabaseColumn(List<OrderItem> meta) {
try {
return objectMapper.writeValueAsString(meta);
} catch (JsonProcessingException ex) {
LOGGER.error("", ex);
return null;
}
}
@Override
public List<OrderItem> convertToEntityAttribute(String dbData) {
try {
if(dbData == null){ //如果dbData为null会导致转换报错,可以根据业务需求对null做处理
return new ArrayList<>();
}
return objectMapper.readValue(dbData, new TypeReference<List<OrderItem>>(){});
} catch (IOException ex) {
LOGGER.error("", ex);
return null;
}
}
}
在字符串转换List,objectMapper.readValue
的类型时TypeReference,这个是与对象转换不同的地方。
2、Order的OrderItem列表添加@Convert注释
import javax.persistence.*;
import java.util.List;
@Entity
@Table(name = "order")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Convert(converter = JSONConverter.class)
private Metadata metadata;
@Convert(converter = ItemsJSONArrayConverter.class)
private List<OrderItem> item;
//get set方法
}